From 55ecf993b4b5402fdde6cd9edad9b605c798ad13 Mon Sep 17 00:00:00 2001 From: Kuan-Po Tseng Date: Wed, 14 Feb 2024 23:09:06 +0800 Subject: [PATCH] [YUNIKORN-2411] Remove Chinese documents (#396) Closes: #396 Signed-off-by: Chia-Ping Tsai --- docs/developer_guide/translation.md | 126 -- docusaurus.config.js | 16 - .../current/api/cluster.md | 78 - .../current/api/scheduler.md | 1617 ----------------- .../current/api/system.md | 225 --- .../current/assets | 1 - .../current/design/preemption.md | 455 ----- .../current/design/scheduler_plugin.md | 89 - .../current/design/simple_preemptor.md | 114 -- .../current/developer_guide/build.md | 186 -- .../current/developer_guide/dependencies.md | 123 -- .../current/developer_guide/env_setup.md | 192 -- .../developer_guide/openshift_development.md | 190 -- .../current/developer_guide/translation.md | 127 -- .../current/get_started/core_features.md | 71 - .../current/get_started/get_started.md | 76 - .../current/get_started/version.md | 57 - .../evaluate_perf_function_with_kubemark.md | 120 -- .../current/performance/metrics.md | 105 -- .../performance/performance_tutorial.md | 451 ----- .../current/performance/profiling.md | 115 -- .../current/user_guide/acls.md | 120 -- .../current/user_guide/deployment_modes.md | 48 - .../current/user_guide/gang_scheduling.md | 297 --- .../labels_and_annotations_in_yunikorn.md | 55 - .../current/user_guide/placement_rules.md | 296 --- .../current/user_guide/prometheus.md | 82 - .../current/user_guide/queue_config.md | 379 ---- .../current/user_guide/resource_quota_mgmt.md | 336 ---- .../current/user_guide/service_config.md | 792 -------- .../current/user_guide/sorting_policies.md | 190 -- .../current/user_guide/troubleshooting.md | 189 -- .../user_guide/usergroup_resolution.md | 121 -- .../current/user_guide/workloads/run_flink.md | 66 - .../current/user_guide/workloads/run_mpi.md | 107 -- .../user_guide/workloads/run_nvidia.md | 347 ---- .../current/user_guide/workloads/run_spark.md | 159 -- .../user_guide/workloads/run_tensorflow.md | 229 --- .../user_guide/workloads/workload_overview.md | 56 - .../version-0.12.1/assets | 1 - .../get_started/core_features.md | 71 - .../version-0.12.1/get_started/get_started.md | 70 - .../version-0.12.1/performance/metrics.md | 109 -- .../performance/performance_tutorial.md | 452 ----- .../user_guide/gang_scheduling.md | 285 --- .../user_guide/trouble_shooting.md | 192 -- .../user_guide/workloads/run_spark.md | 149 -- .../user_guide/workloads/run_tensorflow.md | 93 - .../version-0.12.2/assets | 1 - .../get_started/core_features.md | 71 - .../version-0.12.2/get_started/get_started.md | 70 - .../version-0.12.2/performance/metrics.md | 109 -- .../performance/performance_tutorial.md | 452 ----- .../user_guide/gang_scheduling.md | 285 --- .../user_guide/trouble_shooting.md | 192 -- .../user_guide/workloads/run_spark.md | 149 -- .../user_guide/workloads/run_tensorflow.md | 93 - .../version-1.1.0/assets | 1 - .../get_started/core_features.md | 71 - .../version-1.1.0/get_started/get_started.md | 76 - .../evaluate_perf_function_with_kubemark.md | 120 -- .../version-1.1.0/performance/metrics.md | 105 -- .../performance/performance_tutorial.md | 451 ----- .../version-1.1.0/performance/profiling.md | 115 -- .../user_guide/gang_scheduling.md | 288 --- .../user_guide/trouble_shooting.md | 192 -- .../user_guide/workloads/run_flink.md | 66 - .../user_guide/workloads/run_spark.md | 145 -- .../user_guide/workloads/run_tensorflow.md | 93 - .../version-1.2.0/api/cluster.md | 86 - .../version-1.2.0/assets | 1 - .../get_started/core_features.md | 71 - .../version-1.2.0/get_started/get_started.md | 76 - .../evaluate_perf_function_with_kubemark.md | 120 -- .../version-1.2.0/performance/metrics.md | 105 -- .../performance/performance_tutorial.md | 451 ----- .../version-1.2.0/performance/profiling.md | 115 -- .../user_guide/deployment_modes.md | 48 - .../user_guide/gang_scheduling.md | 296 --- .../user_guide/placement_rules.md | 296 --- .../version-1.2.0/user_guide/queue_config.md | 382 ---- .../user_guide/troubleshooting.md | 189 -- .../user_guide/usergroup_resolution.md | 121 -- .../user_guide/workloads/run_flink.md | 66 - .../user_guide/workloads/run_mpi.md | 107 -- .../user_guide/workloads/run_spark.md | 159 -- .../user_guide/workloads/run_tensorflow.md | 229 --- .../user_guide/workloads/workload_overview.md | 56 - .../version-1.3.0/api/cluster.md | 73 - .../version-1.3.0/api/scheduler.md | 1484 --------------- .../version-1.3.0/api/system.md | 225 --- .../version-1.3.0/assets | 1 - .../developer_guide/env_setup.md | 192 -- .../developer_guide/translation.md | 127 -- .../get_started/core_features.md | 71 - .../version-1.3.0/get_started/get_started.md | 76 - .../evaluate_perf_function_with_kubemark.md | 120 -- .../version-1.3.0/performance/metrics.md | 105 -- .../performance/performance_tutorial.md | 451 ----- .../version-1.3.0/performance/profiling.md | 115 -- .../user_guide/deployment_modes.md | 48 - .../user_guide/gang_scheduling.md | 297 --- .../user_guide/placement_rules.md | 296 --- .../version-1.3.0/user_guide/prometheus.md | 82 - .../version-1.3.0/user_guide/queue_config.md | 382 ---- .../user_guide/resource_quota_mgmt.md | 336 ---- .../user_guide/service_config.md | 792 -------- .../user_guide/sorting_policies.md | 190 -- .../user_guide/troubleshooting.md | 189 -- .../user_guide/usergroup_resolution.md | 121 -- .../user_guide/workloads/run_flink.md | 66 - .../user_guide/workloads/run_mpi.md | 107 -- .../user_guide/workloads/run_spark.md | 159 -- .../user_guide/workloads/run_tensorflow.md | 229 --- .../user_guide/workloads/workload_overview.md | 56 - .../version-1.4.0/api/cluster.md | 78 - .../version-1.4.0/api/scheduler.md | 1484 --------------- .../version-1.4.0/api/system.md | 225 --- .../version-1.4.0/assets | 1 - .../version-1.4.0/design/scheduler_plugin.md | 89 - .../version-1.4.0/design/simple_preemptor.md | 114 -- .../version-1.4.0/developer_guide/build.md | 186 -- .../developer_guide/dependencies.md | 123 -- .../developer_guide/env_setup.md | 192 -- .../developer_guide/openshift_development.md | 190 -- .../developer_guide/translation.md | 127 -- .../get_started/core_features.md | 71 - .../version-1.4.0/get_started/get_started.md | 76 - .../evaluate_perf_function_with_kubemark.md | 120 -- .../version-1.4.0/performance/metrics.md | 105 -- .../performance/performance_tutorial.md | 451 ----- .../version-1.4.0/performance/profiling.md | 115 -- .../version-1.4.0/user_guide/acls.md | 120 -- .../user_guide/deployment_modes.md | 48 - .../user_guide/gang_scheduling.md | 297 --- .../labels_and_annotations_in_yunikorn.md | 55 - .../user_guide/placement_rules.md | 296 --- .../version-1.4.0/user_guide/prometheus.md | 82 - .../version-1.4.0/user_guide/queue_config.md | 382 ---- .../user_guide/resource_quota_mgmt.md | 336 ---- .../user_guide/service_config.md | 792 -------- .../user_guide/sorting_policies.md | 190 -- .../user_guide/troubleshooting.md | 189 -- .../user_guide/usergroup_resolution.md | 121 -- .../user_guide/workloads/run_flink.md | 66 - .../user_guide/workloads/run_mpi.md | 107 -- .../user_guide/workloads/run_nvidia.md | 347 ---- .../user_guide/workloads/run_spark.md | 159 -- .../user_guide/workloads/run_tensorflow.md | 229 --- .../user_guide/workloads/workload_overview.md | 56 - .../community/coding_guidelines.md | 153 -- .../community/download.md | 88 - .../community/events.md | 79 - .../community/get_involved.md | 89 - .../community/how_to_contribute.md | 111 -- .../community/people.md | 109 -- .../community/release_procedure.md | 339 ---- .../community/reporting_issues.md | 101 - .../community/roadmap.md | 54 - .../zh-cn/docusaurus-plugin-content-pages/img | 1 - .../docusaurus-plugin-content-pages/index.js | 167 -- .../release-announce/0.10.0.md | 54 - .../release-announce/0.11.0.md | 57 - .../release-announce/0.12.1.md | 61 - .../release-announce/0.12.2.md | 56 - .../release-announce/0.8.0.md | 65 - .../release-announce/0.9.0.md | 63 - .../release-announce/1.0.0.md | 135 -- .../release-announce/1.1.0.md | 55 - .../release-announce/1.2.0.md | 72 - .../release-announce/1.3.0.md | 87 - .../release-announce/1.4.0.md | 97 - .../styles.module.css | 1 - .../docusaurus-theme-classic/footer.json | 17 - .../docusaurus-theme-classic/navbar.json | 50 - local-build.sh | 2 +- sidebars.js | 1 - .../developer_guide/translation.md | 126 -- .../developer_guide/translation.md | 126 -- .../developer_guide/translation.md | 126 -- .../version-1.2.0-sidebars.json | 1 - .../version-1.3.0-sidebars.json | 1 - .../version-1.4.0-sidebars.json | 1 - 183 files changed, 1 insertion(+), 32497 deletions(-) delete mode 100644 docs/developer_guide/translation.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/api/cluster.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/api/scheduler.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/api/system.md delete mode 120000 i18n/zh-cn/docusaurus-plugin-content-docs/current/assets delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/design/preemption.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/design/scheduler_plugin.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/design/simple_preemptor.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/build.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/dependencies.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/env_setup.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/openshift_development.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/translation.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/core_features.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/get_started.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/version.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/evaluate_perf_function_with_kubemark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/metrics.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/performance_tutorial.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/profiling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/acls.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/deployment_modes.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/gang_scheduling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/labels_and_annotations_in_yunikorn.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/placement_rules.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/prometheus.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/queue_config.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/resource_quota_mgmt.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/service_config.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/sorting_policies.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/troubleshooting.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/usergroup_resolution.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_flink.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_mpi.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_nvidia.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_spark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_tensorflow.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/workload_overview.md delete mode 120000 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/assets delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/get_started/core_features.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/get_started/get_started.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/performance/metrics.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/performance/performance_tutorial.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/gang_scheduling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/trouble_shooting.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/workloads/run_spark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/workloads/run_tensorflow.md delete mode 120000 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/assets delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/get_started/core_features.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/get_started/get_started.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/performance/metrics.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/performance/performance_tutorial.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/gang_scheduling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/trouble_shooting.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/workloads/run_spark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/workloads/run_tensorflow.md delete mode 120000 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/assets delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/get_started/core_features.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/get_started/get_started.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/evaluate_perf_function_with_kubemark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/metrics.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/performance_tutorial.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/profiling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/gang_scheduling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/trouble_shooting.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/workloads/run_flink.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/workloads/run_spark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/workloads/run_tensorflow.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/api/cluster.md delete mode 120000 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/assets delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/get_started/core_features.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/get_started/get_started.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/evaluate_perf_function_with_kubemark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/metrics.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/performance_tutorial.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/profiling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/deployment_modes.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/gang_scheduling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/placement_rules.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/queue_config.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/troubleshooting.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/usergroup_resolution.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_flink.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_mpi.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_spark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_tensorflow.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/workload_overview.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/cluster.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/scheduler.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/system.md delete mode 120000 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/assets delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/developer_guide/env_setup.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/developer_guide/translation.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/get_started/core_features.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/get_started/get_started.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/evaluate_perf_function_with_kubemark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/metrics.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/performance_tutorial.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/profiling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/deployment_modes.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/gang_scheduling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/placement_rules.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/prometheus.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/queue_config.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/resource_quota_mgmt.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/service_config.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/sorting_policies.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/troubleshooting.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/usergroup_resolution.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_flink.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_mpi.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_spark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_tensorflow.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/workload_overview.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/cluster.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/scheduler.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/system.md delete mode 120000 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/assets delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/design/scheduler_plugin.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/design/simple_preemptor.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/build.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/dependencies.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/env_setup.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/openshift_development.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/translation.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/get_started/core_features.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/get_started/get_started.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/evaluate_perf_function_with_kubemark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/metrics.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/performance_tutorial.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/profiling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/acls.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/deployment_modes.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/gang_scheduling.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/labels_and_annotations_in_yunikorn.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/placement_rules.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/prometheus.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/queue_config.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/resource_quota_mgmt.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/service_config.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/sorting_policies.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/troubleshooting.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/usergroup_resolution.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_flink.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_mpi.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_nvidia.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_spark.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_tensorflow.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/workload_overview.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/community/coding_guidelines.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/community/download.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/community/events.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/community/get_involved.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/community/how_to_contribute.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/community/people.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/community/release_procedure.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/community/reporting_issues.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/community/roadmap.md delete mode 120000 i18n/zh-cn/docusaurus-plugin-content-pages/img delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/index.js delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.10.0.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.11.0.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.12.1.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.12.2.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.8.0.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.9.0.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.0.0.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.1.0.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.2.0.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.3.0.md delete mode 100644 i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.4.0.md delete mode 120000 i18n/zh-cn/docusaurus-plugin-content-pages/styles.module.css delete mode 100644 i18n/zh-cn/docusaurus-theme-classic/footer.json delete mode 100644 i18n/zh-cn/docusaurus-theme-classic/navbar.json delete mode 100644 versioned_docs/version-1.2.0/developer_guide/translation.md delete mode 100644 versioned_docs/version-1.3.0/developer_guide/translation.md delete mode 100644 versioned_docs/version-1.4.0/developer_guide/translation.md diff --git a/docs/developer_guide/translation.md b/docs/developer_guide/translation.md deleted file mode 100644 index 2ab5a0d3188..00000000000 --- a/docs/developer_guide/translation.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: translation -title: Translation ---- - - - -Yunikorn website adopting Docusaurus manages documentations. -[Docusaurus i18n system](https://docusaurus.io/docs/i18n/tutorial) allows developer to translate documentations. -For adding a new language translation, developers should do following operations. - -## Modifying the docusaurus.config.js for supporting the new language -Assume the translations by a **new language keyword**. -Expected results will be like this figure. -![translation results](./../assets/translationDemo.png) - -Current Yunikorn website include the en and zh-cn documentaions. -If developer want to add a new translation with **new language keyword** including fr, jp, the developers need to modify the `i18n` in `docusaurus.config.js`. -``` -i18n: { - defaultLocale: 'en', - locales: ['en', 'zh-cn', ''], - localeConfigs: { - en: { - label: 'English', - }, - "zh-cn": { - label: '中文', - }, - "": { - label: 'test', - } - }, - }, -``` -## Updating the help information in local-build.sh -Adding the **new language keyword** to the locale list in `print_usage` function. -``` -Usage: $(basename "$0") run [locale] | build | clean | help - run build the website, and launch the server in a docker image. - a locale can be specified, currently supported: "en", "zh-cn", "" -``` - -## Copying latest files to i18n -``` -mkdir -p i18n//docusaurus-plugin-content-docs/current -cp -r docs/** i18n//docusaurus-plugin-content-docs/current -mkdir -p i18n//docusaurus-plugin-content-pages -cp -r src/pages/** i18n//docusaurus-plugin-content-pages -mkdir -p i18n//docusaurus-theme-classic -``` - -## Adding the translated information in sidebar.json and footer.json -Create sidebar.json and and footer.json in docusaurus-theme-classic. -For example, the footer.json context is following. -``` -{ - "link.item.label.Get Involved": { - "message": "参与" - }, - "link.title.Code Repositories": { - "message": "代码库" - }, - "link.item.label.People": { - "message": "人们" - }, - "link.title.Blog": { - "message": "博客" - }, - "link.title.Community": { - "message": "社区" - } -} -``` - - - -## linking img, assest and styles.module.css -Creating linking files in the `i18n/new language keyword/docusaurus-plugin-content-pages`. - -``` -# cleaning the duplicate files -rm -rf img -rm styles.module.css -# linking -ln -s ../../../static/img -ln -s ../../../src/pages/styles.module.css -``` - -Creating the linking file in the 'i18n/new language keyword/docusaurus-plugin-content-docs/current'. -``` -# cleaning the duplicate files -rm -rf assests -# linking -ln -s ../../../../docs/assets -``` - -## Adopting relative paths -There are some image urls adopting absolute path in `src/pages/index.js` and adopting absolute path could cause png missing. -Developers could make sure that the img link in `/i18n/new language keyword/docusaurus-plugin-content-pages/index.js` is work. -For example, there is a `resource-scheduling.png` in `index.js` and the png url is `/img/resource-scheduling.png`. -``` -/img/resource-scheduling.png -> ./img/resource-scheduling.png -``` -## Test -``` -./local-build.sh run -``` -![Building website](./../assets/translationBuilding.png) diff --git a/docusaurus.config.js b/docusaurus.config.js index cf03092a2a7..782d030c218 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -27,18 +27,6 @@ module.exports = { customFields: { trailingSlashes: true, }, - i18n: { - defaultLocale: 'en', - locales: ['en', 'zh-cn'], - localeConfigs: { - en: { - label: 'English', - }, - "zh-cn": { - label: '中文', - }, - }, - }, presets: [ [ '@docusaurus/preset-classic', @@ -157,10 +145,6 @@ module.exports = { type: 'docsVersionDropdown', position: 'right', }, - { - type: 'localeDropdown', - position: 'right', - }, { href: 'https://github.com/apache/yunikorn-core', position: 'right', diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/api/cluster.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/api/cluster.md deleted file mode 100644 index 48f25f82ae8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/api/cluster.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -id: cluster -title: 集群 ---- - - - -## 集群 - -回传 Yunikorn 所管理的集群信息,像是资源管理器的构建信息。 - -**位置(URL)** : `/ws/v1/clusters` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**回传代码**:`200 OK` - -**示例** - -在本示例中,响应的内容来自一个群集,拥有一个资源管理器。 - -```json -[ - { - "startTime": 1697100824863892713, - "rmBuildInformation": [ - { - "arch": "amd64", - "buildDate": "2023-09-04T18:11:43+0800", - "buildVersion": "latest", - "coreSHA": "0ecf24d2aad2", - "goVersion": "1.21", - "isPluginVersion": "false", - "rmId": "mycluster", - "shimSHA": "8b26c373b4b5", - "siSHA": "e7622cf54e95" - } - ], - "partition": "default", - "clusterName": "kubernetes" - } -] -``` - -### 出错时的响应 - -**回传代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/api/scheduler.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/api/scheduler.md deleted file mode 100644 index 9325c4c03ef..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/api/scheduler.md +++ /dev/null @@ -1,1617 +0,0 @@ ---- -id: scheduler -title: 调度器 ---- - - - -# 概要 - -Yunikorn调度器能透过REST API来返回多个对象的信息 -其中许多API将回传资源集合。在内部中,所有资源被「有符号的64位整数类型」所表示。当解析REST API的响应时,类型为`memory`的资源以bytes作为单位,而`vcore`则以一千表示一个CPU核心。而这两类之外的其他资源种类则没有具体指定。 - -在与app/node相关调用的响应中,包含一个`allocations`字段,而该字段中也包含多个字段。如`placeholderUsed`指的是分配是否是取代占位符(placeholder)。如果为true,`requestTime`将代表的是占位符的创建时间,如果为false,则就是代表这个分配(allocation)被询问时的时间。`allocationTime`则为分配被创建的时间,`allocationDelay`,则为`allocationTime`和`requestTime `相差的时间。 - -## 分区(Partitions) - -显示有关分区的一般信息和统计数据。 - -**位置(URL)**:`/ws/v1/partitions` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -```json -[ - { - "clusterId": "mycluster", - "name": "default", - "state": "Active", - "lastStateTransitionTime": 1649167576110754000, - "capacity": { - "capacity": { - "ephemeral-storage": 188176871424, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 1000000000, - "pods": 330, - "vcore": 1000 - }, - "usedCapacity": { - "memory": 800000000, - "vcore": 500 - }, - "utilization": { - "memory": 80, - "vcore": 50 - } - }, - "nodeSortingPolicy": { - "type": "fair", - "resourceWeights": { - "memory": 1.5, - "vcore": 1.3 - } - }, - "applications": { - "New": 5, - "Pending": 5, - "total": 10 - }, - "totalContainers": 0, - "totalNodes": 2 - }, - { - "clusterId": "mycluster", - "name": "gpu", - "state": "Active", - "lastStateTransitionTime": 1649167576111236000, - "capacity": { - "capacity": { - "memory": 2000000000, - "vcore": 2000 - }, - "usedCapacity": { - "memory": 500000000, - "vcore": 300 - }, - "utilization": { - "memory": 25, - "vcore": 15 - } - }, - "nodeSortingPolicy": { - "type": "binpacking", - "resourceWeights": { - "memory": 0, - "vcore": 4.11 - } - }, - "applications": { - "New": 5, - "Running": 10, - "Pending": 5, - "total": 20 - }, - "totalContainers": 20, - "totalNodes": 5 - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 队列(Queues) - -### 分区队列 - -获取给定分区中的队列,及队列相关的信息,其中包含名称、状态、容量和属性。 -队列层次结构(hierarchy)被保留在响应的json档中。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/queues` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -在预设的队列层次结构中(仅`root.default`),将会向客户端发送与以下相似的响应。 - -```json -[ - { - "queuename": "root", - "status": "Active", - "maxResource": { - "ephemeral-storage": 188176871424, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 8000000000, - "pods": 330, - "vcore": 8000 - }, - "guaranteedResource": { - "memory": 54000000, - "vcore": 80 - }, - "allocatedResource": { - "memory": 54000000, - "vcore": 80 - }, - "isLeaf": "false", - "isManaged": "false", - "properties": { - "application.sort.policy": "stateaware" - }, - "parent": "", - "template": { - "maxResource": { - "memory": 8000000000, - "vcore": 8000 - }, - "guaranteedResource": { - "memory": 54000000, - "vcore": 80 - }, - "properties": { - "application.sort.policy": "stateaware" - } - }, - "partition": "default", - "children": [ - { - "queuename": "root.default", - "status": "Active", - "maxResource": { - "memory": 8000000000, - "vcore": 8000 - }, - "guaranteedResource": { - "memory": 54000000, - "vcore": 80 - }, - "allocatedResource": { - "memory": 54000000, - "vcore": 80 - }, - "isLeaf": "true", - "isManaged": "false", - "properties": { - "application.sort.policy": "stateaware" - }, - "parent": "root", - "template": null, - "children": [], - "absUsedCapacity": { - "memory": 1, - "vcore": 0 - }, - "maxRunningApps": 12, - "runningApps": 4, - "allocatingAcceptedApps": [ - "app-1", - "app-2" - ] - } - ], - "absUsedCapacity": { - "memory": 1, - "vcore": 0 - } - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 多个应用程序 - -### 队列中多个应用程序 - -获取给定分区/队列组合的所有应用程序,并显示有关应用程序的信息,如使用的资源、队列名称、提交时间和分配。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/queue/{queueName}/applications` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -在下面的示例中,有三个分配属于两个应用程序,其中一个具有挂起(Pending)的请求。 - -```json -[ - { - "applicationID": "application-0001", - "usedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "maxUsedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "partition": "default", - "queueName": "root.default", - "submissionTime": 1648754032076020293, - "requests": [ - { - "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task2" - }, - "requestTime": 16487540320812345678, - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "pendingCount": 1, - "priority": "0", - "requiredNodeId": "", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderTimeout": 0, - "taskGroupName": "", - "allocationLog": [ - { - "message": "node(s) didn't match Pod's node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate", - "lastOccurrence": 16487540320812346001, - "count": 81 - }, - { - "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346002, - "count": 504 - }, - { - "message": "node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346003, - "count": 1170 - } - ] - } - ], - "allocations": [ - { - "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": true - } - ], - "applicationState": "Running", - "user": "system:serviceaccount:kube-system:deployment-controller", - "groups": [ - "system:serviceaccounts", - "system:serviceaccounts:kube-system", - "system:authenticated" - ], - "rejectedMessage": "", - "stateLog": [ - { - "time": 1648741409145224000, - "applicationState": "Accepted" - }, - { - "time": 1648741409145509400, - "applicationState": "Starting" - }, - { - "time": 1648741409147432100, - "applicationState": "Running" - } - ], - "placeholderData": [ - { - "taskGroupName": "task-group-example", - "count": 2, - "minResource": { - "memory": 1000000000, - "vcore": 100 - }, - "replaced": 1, - "timedout": 1 - } - ] - }, - { - "applicationID": "application-0002", - "usedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "maxUsedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "partition": "default", - "queueName": "root.default", - "submissionTime": 1648754032076020293, - "requests": [], - "allocations": [ - { - "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0002", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "08033f9a-4699-403c-9204-6333856b41bd", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0002", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - }, - { - "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0002", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task1" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0002", - "applicationId": "application-0002", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - } - ], - "applicationState": "Running", - "user": "system:serviceaccount:kube-system:deployment-controller", - "groups": [ - "system:serviceaccounts", - "system:serviceaccounts:kube-system", - "system:authenticated" - ], - "rejectedMessage": "", - "stateLog": [ - { - "time": 1648741409145224000, - "applicationState": "Accepted" - }, - { - "time": 1648741409145509400, - "applicationState": "Starting" - }, - { - "time": 1648741409147432100, - "applicationState": "Running" - } - ], - "placeholderData": [] - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 单一应用程序 - -### 队列中单一应用程序 - -从给定分区、队列和应用程序ID来获取应用程序,并显示有关应用程序的信息,如使用的资源、队列名称、提交时间和分配。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/queue/{queueName}/application/{appId}` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -```json -{ - "applicationID": "application-0001", - "usedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "maxUsedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "partition": "default", - "queueName": "root.default", - "submissionTime": 1648754032076020293, - "requests": [ - { - "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task2" - }, - "requestTime": 16487540320812345678, - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "pendingCount": 1, - "priority": "0", - "requiredNodeId": "", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderTimeout": 0, - "taskGroupName": "", - "allocationLog": [ - { - "message": "node(s) didn't match Pod's node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate", - "lastOccurrence": 16487540320812346001, - "count": 81 - }, - { - "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346002, - "count": 504 - }, - { - "message": "node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346003, - "count": 1170 - } - ] - } - ], - "allocations": [ - { - "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": true - } - ], - "applicationState": "Running", - "user": "system:serviceaccount:kube-system:deployment-controller", - "groups": [ - "system:serviceaccounts", - "system:serviceaccounts:kube-system", - "system:authenticated" - ], - "rejectedMessage": "", - "stateLog": [ - { - "time": 1648741409145224000, - "applicationState": "Accepted" - }, - { - "time": 1648741409145509400, - "applicationState": "Starting" - }, - { - "time": 1648741409147432100, - "applicationState": "Running" - } - ], - "placeholderData": [ - { - "taskGroupName": "task-group-example", - "count": 2, - "minResource": { - "memory": 1000000000, - "vcore": 100 - }, - "replaced": 1, - "timedout": 1 - } - ] -} -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 多个节点 - -### 分区中多个节点 - -获取给定分区的所有节点,并显示由YuniKorn管理的节点的信息。 -节点详细信息包括主机和机架名称、容量、资源、利用率和分配。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/nodes` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -这个示例的响应,来自一个群集,其中包含2个节点和3个分配。 - -```json -[ - { - "nodeID": "node-0001", - "hostName": "", - "rackName": "", - "capacity": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 14577000000, - "pods": 110, - "vcore": 10000 - }, - "allocated": { - "memory": 6000000000, - "vcore": 6000 - }, - "occupied": { - "memory": 154000000, - "vcore" :750 - }, - "available": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 6423000000, - "pods": 110, - "vcore": 1250 - }, - "utilized": { - "memory": 3, - "vcore": 13 - }, - "allocations": [ - { - "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "08033f9a-4699-403c-9204-6333856b41bd", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - }, - { - "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0002", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0002", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - } - ], - "schedulable": true - }, - { - "nodeID": "node-0002", - "hostName": "", - "rackName": "", - "capacity": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 14577000000, - "pods": 110, - "vcore": 10000 - }, - "allocated": { - "memory": 2000000000, - "vcore": 2000 - }, - "occupied": { - "memory": 154000000, - "vcore" :750 - }, - "available": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 6423000000, - "pods": 110, - "vcore": 1250 - }, - "utilized": { - "memory": 8, - "vcore": 38 - }, - "allocations": [ - { - "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task1" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0002", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - } - ], - "schedulable": true - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 单一节点 - -### 分区中单一节点 - -从给定分区和节点ID来获取节点,并显示有关节点的信息,节点详细信息包括主机和机架名称、容量、资源、利用率和分配。 - -**位置(URL)** : `/ws/v1/partition/{partitionName}/node/{nodeId}` - -**方法(Method)** : `GET` - -**需求权限** : NO - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -{ - "nodeID":"node-0001", - "hostName":"", - "rackName":"", - "capacity":{ - "ephemeral-storage":75850798569, - "hugepages-1Gi":0, - "hugepages-2Mi":0, - "memory":14577000000, - "pods":110, - "vcore":10000 - }, - "allocated":{ - "memory":6000000000, - "vcore":6000 - }, - "occupied":{ - "memory":154000000, - "vcore":750 - }, - "available":{ - "ephemeral-storage":75850798569, - "hugepages-1Gi":0, - "hugepages-2Mi":0, - "memory":6423000000, - "pods":110, - "vcore":1250 - }, - "utilized":{ - "memory":3, - "vcore":13 - }, - "allocations":[ - { - "allocationKey":"54e5d77b-f4c3-4607-8038-03c9499dd99d", - "allocationTags":{ - "kubernetes.io/label/app":"sleep", - "kubernetes.io/label/applicationId":"application-0001", - "kubernetes.io/label/queue":"root.default", - "kubernetes.io/meta/namespace":"default", - "kubernetes.io/meta/podName":"task0" - }, - "requestTime":1648754034098912461, - "allocationTime":1648754035973982920, - "allocationDelay":1875070459, - "uuid":"08033f9a-4699-403c-9204-6333856b41bd", - "resource":{ - "memory":2000000000, - "vcore":2000 - }, - "priority":"0", - "nodeId":"node-0001", - "applicationId":"application-0001", - "partition":"default", - "placeholder":false, - "placeholderUsed":false - }, - { - "allocationKey":"deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags":{ - "kubernetes.io/label/app":"sleep", - "kubernetes.io/label/applicationId":"application-0002", - "kubernetes.io/label/queue":"root.default", - "kubernetes.io/meta/namespace":"default", - "kubernetes.io/meta/podName":"task0" - }, - "requestTime":1648754034098912461, - "allocationTime":1648754035973982920, - "allocationDelay":1875070459, - "uuid":"9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource":{ - "memory":4000000000, - "vcore":4000 - }, - "priority":"0", - "nodeId":"node-0001", - "applicationId":"application-0002", - "partition":"default", - "placeholder":false, - "placeholderUsed":false - } - ], - "schedulable":true -} -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 节点主要资源使用率 - -每个节点在主要资源利用率的分布。 - -**状态 (Status)** : 自v1.5.0起已被弃用,并将在下一个主要版本中移除。替代为 `/ws/v1/scheduler/node-utilizations`。 - -**位置(URL)** : `/ws/v1/scheduler/node-utilization` - -**方法(Method)** : `GET` - -**需求权限** : NO - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -{ - "type": "vcore", - "utilization": [ - { - "bucketName": "0-10%", - "numOfNodes": 1, - "nodeNames": [ - "aethergpu" - ] - }, - { - "bucketName": "10-20%", - "numOfNodes": 2, - "nodeNames": [ - "primary-node", - "second-node" - ] - }, - ... - ] -} -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 节点资源使用率 - -每个节点各种资源的利用率分布。 - -**位置(URL)** : `/ws/v1/scheduler/node-utilizations` - -**方法(Method)** : `GET` - -**需求权限** : NO - -### 成功时的响应 - -**返回代码** :`200 OK` - -**示例** - -```json -[ - { - "clusterId": "mycluster", - "partition": "default", - "utilizations": [ - { - "type": "pods", - "utilization": [ - { - "bucketName": "0-10%", - "numOfNodes": 2, - "nodeNames": [ - "primary-node", - "second-node" - ] - }, - { - "bucketName": "10-20%" - }, - ... - ] - }, - { - "type": "vcores", - "utilization": [ - { - "bucketName": "0-10%", - "numOfNodes": 2, - "nodeNames": [ - "primary-node", - "second-node" - ] - }, - { - "bucketName": "10-20%" - }, - ... - ] - }, - ... - ] - } -] -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## Goroutines信息 - -获取当前运行的goroutines的堆栈跟踪(stack traces) - -**位置(URL)**:`/ws/v1/stack` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -```text -goroutine 356 [running -]: -github.com/apache/yunikorn-core/pkg/webservice.getStackInfo.func1(0x30a0060, -0xc003e900e0, -0x2) - /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 41 +0xab -github.com/apache/yunikorn-core/pkg/webservice.getStackInfo(0x30a0060, -0xc003e900e0, -0xc00029ba00) - /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 48 +0x71 -net/http.HandlerFunc.ServeHTTP(0x2df0e10, -0x30a0060, -0xc003e900e0, -0xc00029ba00) - /usr/local/go/src/net/http/server.go: 1995 +0x52 -github.com/apache/yunikorn-core/pkg/webservice.Logger.func1(0x30a0060, -0xc003e900e0, -0xc00029ba00) - /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/webservice.go: 65 +0xd4 -net/http.HandlerFunc.ServeHTTP(0xc00003a570, -0x30a0060, -0xc003e900e0, -0xc00029ba00) - /usr/local/go/src/net/http/server.go: 1995 +0x52 -github.com/gorilla/mux.(*Router).ServeHTTP(0xc00029cb40, -0x30a0060, -0xc003e900e0, -0xc0063fee00) - /yunikorn/go/pkg/mod/github.com/gorilla/mux@v1.7.3/mux.go: 212 +0x140 -net/http.serverHandler.ServeHTTP(0xc0000df520, -0x30a0060, -0xc003e900e0, -0xc0063fee00) - /usr/local/go/src/net/http/server.go: 2774 +0xcf -net/http.(*conn).serve(0xc0000eab40, -0x30a61a0, -0xc003b74000) - /usr/local/go/src/net/http/server.go: 1878 +0x812 -created by net/http.(*Server).Serve - /usr/local/go/src/net/http/server.go: 2884 +0x4c5 - -goroutine 1 [chan receive, - 26 minutes -]: -main.main() - /yunikorn/pkg/shim/main.go: 52 +0x67a - -goroutine 19 [syscall, - 26 minutes -]: -os/signal.signal_recv(0x1096f91) - /usr/local/go/src/runtime/sigqueue.go: 139 +0x9f -os/signal.loop() - /usr/local/go/src/os/signal/signal_unix.go: 23 +0x30 -created by os/signal.init.0 - /usr/local/go/src/os/signal/signal_unix.go: 29 +0x4f - -... -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 指标(Metrics) - -从Prometheus服务器检索指标的端点。 -指标中包含帮助消息和类型信息(type information)。 - -**位置(URL)** : `/ws/v1/metrics` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```text -# HELP go_gc_duration_seconds 作为垃圾收集周期的暂停期间的摘要。 -# TYPE go_gc_duration_seconds summary -go_gc_duration_seconds{quantile="0"} 2.567e-05 -go_gc_duration_seconds{quantile="0.25"} 3.5727e-05 -go_gc_duration_seconds{quantile="0.5"} 4.5144e-05 -go_gc_duration_seconds{quantile="0.75"} 6.0024e-05 -go_gc_duration_seconds{quantile="1"} 0.00022528 -go_gc_duration_seconds_sum 0.021561648 -go_gc_duration_seconds_count 436 -# HELP go_goroutines 当前存在的goroutines数量。 -# TYPE go_goroutines gauge -go_goroutines 82 -# HELP go_info 关于Golang环境的信息。 -# TYPE go_info gauge -go_info{version="go1.12.17"} 1 -# HELP go_memstats_alloc_bytes 已经被分配且正在使用的记忆体位元(bytes)数。 -# TYPE go_memstats_alloc_bytes gauge -go_memstats_alloc_bytes 9.6866248e+07 - -... - -# HELP yunikorn_scheduler_vcore_nodes_usage 节点的CPU使用量 -# TYPE yunikorn_scheduler_vcore_nodes_usage gauge -yunikorn_scheduler_vcore_nodes_usage{range="(10%, 20%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(20%,30%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(30%,40%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(40%,50%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(50%,60%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(60%,70%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(70%,80%]"} 1 -yunikorn_scheduler_vcore_nodes_usage{range="(80%,90%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(90%,100%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="[0,10%]"} 0 -``` - -## 配置验证 - -**位置(URL)** : `/ws/v1/validate-conf` - -**方法(Method)** : `POST` - -**需求权限**:无 - -### 成功时的响应 - -无论配置是否被允许,如果服务器能够处理请求,它都将生成一个200HTTP状态代码。 - -**返回代码** : `200 OK` - -#### 允许的配置 - -发送以下简单配置会被接受 - -```yaml -partitions: - - name: default - queues: - - name: root - queues: - - name: test -``` - -返回 - -```json -{ - "allowed": true, - "reason": "" -} -``` - -#### 不允许的配置 - -由于以下的的yaml档案中包含了“wrong_text”字段,因此是不允许的配置。 - -```yaml -partitions: - - name: default - queues: - - name: root - queues: - - name: test - - wrong_text -``` - -返回 - -```json -{ - "allowed": false, - "reason": "yaml: unmarshal errors:\n line 7: cannot unmarshal !!str `wrong_text` into configs.PartitionConfig" -} -``` - -## 配置 - -检索当前调度器配置的端点 - -**位置(URL)** : `/ws/v1/config` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```yaml -partitions: -- name: default - queues: - - name: root - parent: true - submitacl: '*' - placementrules: - - name: tag - create: true - value: namespace -checksum: D75996C07D5167F41B33E27CCFAEF1D5C55BE3C00EE6526A7ABDF8435DB4078E -``` - -## 应用程序历史 - -检索历史数据的端点,依据时间来条列应用程序的总数。 - -**位置(URL)** : `/ws/v1/history/apps` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -[ - { - "timestamp": 1595939966153460000, - "totalApplications": "1" - }, - { - "timestamp": 1595940026152892000, - "totalApplications": "1" - }, - { - "timestamp": 1595940086153799000, - "totalApplications": "2" - }, - { - "timestamp": 1595940146154497000, - "totalApplications": "2" - }, - { - "timestamp": 1595940206155187000, - "totalApplications": "2" - } -] -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 容器历史 - -检索历史数据的端点,依据时间来条列容器的总数。 - -**位置(URL)** : `/ws/v1/history/containers` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -[ - { - "timestamp": 1595939966153460000, - "totalContainers": "1" - }, - { - "timestamp": 1595940026152892000, - "totalContainers": "1" - }, - { - "timestamp": 1595940086153799000, - "totalContainers": "3" - }, - { - "timestamp": 1595940146154497000, - "totalContainers": "3" - }, - { - "timestamp": 1595940206155187000, - "totalContainers": "3" - } -] -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - - -## 健康检查的端点 - -用来检索历史数据的端点,其中包含关键日志,以及节点、集群、应用程序中资源量为负的资源。 - -**位置(URL)** : `/ws/v1/scheduler/healthcheck` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -{ - "Healthy": true, - "HealthChecks": [ - { - "Name": "Scheduling errors", - "Succeeded": true, - "Description": "Check for scheduling error entries in metrics", - "DiagnosisMessage": "There were 0 scheduling errors logged in the metrics" - }, - { - "Name": "Failed nodes", - "Succeeded": true, - "Description": "Check for failed nodes entries in metrics", - "DiagnosisMessage": "There were 0 failed nodes logged in the metrics" - }, - { - "Name": "Negative resources", - "Succeeded": true, - "Description": "Check for negative resources in the partitions", - "DiagnosisMessage": "Partitions with negative resources: []" - }, - { - "Name": "Negative resources", - "Succeeded": true, - "Description": "Check for negative resources in the nodes", - "DiagnosisMessage": "Nodes with negative resources: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if a node's allocated resource <= total resource of the node", - "DiagnosisMessage": "Nodes with inconsistent data: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if total partition resource == sum of the node resources from the partition", - "DiagnosisMessage": "Partitions with inconsistent data: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if node total resource = allocated resource + occupied resource + available resource", - "DiagnosisMessage": "Nodes with inconsistent data: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if node capacity >= allocated resources on the node", - "DiagnosisMessage": "Nodes with inconsistent data: []" - }, - { - "Name": "Reservation check", - "Succeeded": true, - "Description": "Check the reservation nr compared to the number of nodes", - "DiagnosisMessage": "Reservation/node nr ratio: [0.000000]" - } - ] -} -``` - -## 检索所有状态 - -能在单一响应包含以下的信息: - -* 分区清单 -* 应用程序清单(`运行中` 和 `已完成`) -* 应用程序历史 -* 节点 -* 节点的使用率 -* 集群的基本信息 -* 集群的使用率 -* 容器的历史 -* 队列 -* RM 诊断 - -**位置(URL)** : `/ws/v1/fullstatedump` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -该REST请求的输出将会很巨大,且为前面演示过的输出的组合。 - -RM 诊断显示 K8Shim 缓存的内容。确切内容取决于版本并且尚未稳定。 -当前内容显示缓存的对象: -* 节点 -* pods -* 优先等级 -* 调度状态(pod状态) - -### 错误时的响应 - -**代码**:`500 Internal Server Error` - -## 启用或禁用定期写入状态信息 - -为允许状态周期性地写入的端点。 - -**状态**:自v1.2.0以来已弃用并被忽略,无替代品。 - -**位置(URL)** : `/ws/v1/periodicstatedump/{switch}/{periodSeconds}` - -**方法(Method)** : `PUT` - -**需求权限**:无 - -### 成功时的响应 - -无 - -### 错误时的响应 - -**代码**: `400 Bad Request` - -## 获取日志级别 -接收当前Yunikorn的日志级别。 - -**URL** : `/ws/v1/loglevel` - -**方法** : `GET` - -**需求权限** : 无 - -### 成功时的响应 - -**代码**: `200 OK` - -**示例** - -``` -info% -``` - -## 设置日志级别 -设置Yunikorn日志级别。 - -**URL** : `/ws/v1/loglevel/{level}` - -**方法** : `PUT` - -**需求权限** : NO - -### 成功时的响应 - -**代码**: `200 OK` - -### 错误时的响应 - -**代码**: `400 Bad Request` - -**示例** - -```json -{ - "status_code":400, - "message":"failed to change log level, old level active", - "description":"failed to change log level, old level active" -} -``` - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/api/system.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/api/system.md deleted file mode 100644 index 83337cf4bc3..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/api/system.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -id: system -title: 系統 ---- - - - -这些端点是用于提供資訊給[pprof](https://github.com/google/pprof)分析工具。 - -## pprof - -**位置(URL)** : `/debug/pprof/` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```text -/debug/pprof/ - -Types of profiles available: -Count Profile -273 allocs -0 block -0 cmdline -78 goroutine -273 heap -0 mutex -0 profile -29 threadcreate -0 trace -full goroutine stack dump -Profile Descriptions: - -allocs: A sampling of all past memory allocations -block: Stack traces that led to blocking on synchronization primitives -cmdline: The command line invocation of the current program -goroutine: Stack traces of all current goroutines -heap: A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample. -mutex: Stack traces of holders of contended mutexes -profile: CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile. -threadcreate: Stack traces that led to the creation of new OS threads -trace: A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace. -``` - -## 堆 (Heap) - -**位置(URL)** : `/debug/pprof/heap` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 线程创建 - -**位置(URL)** : `/debug/pprof/threadcreate` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## Goroutine - -**位置(URL)** : `/debug/pprof/goroutine` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 分配 (Allocations) - -**位置(URL)** : `/debug/pprof/allocs` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 阻塞分析 (Block) - -**位置(URL)** : `/debug/pprof/block` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 互斥锁分析 (Mutex) - -**位置(URL)** : `/debug/pprof/mutex` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 命令行参数 (Cmdline) - -**位置(URL)** : `/debug/pprof/cmdline` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 简介 - -**位置(URL)** : `/debug/pprof/profile` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## Symbol - -**位置(URL)** : `/debug/pprof/symbol` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 跟踪(Trace) - -**位置(URL)** : `/debug/pprof/trace` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/assets b/i18n/zh-cn/docusaurus-plugin-content-docs/current/assets deleted file mode 120000 index 778d0f8e471..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/assets +++ /dev/null @@ -1 +0,0 @@ -../../../../docs/assets \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/design/preemption.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/design/preemption.md deleted file mode 100644 index 826636df3f2..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/design/preemption.md +++ /dev/null @@ -1,455 +0,0 @@ ---- -id: preemption -title: 抢佔 ---- - - - -# 抢佔式设计 - -## 简介 - -在过去很长一段时间以来,YuniKorn 的部份代码中都包含了抢佔代码,这个设计是为了去替换掉这些内容。 - -原始代码并没有经过充分测试。 -在 [YUNIKORN-317](https://issues.apache.org/jira/browse/YUNIKORN-317) 移除核心的快取后,抢佔代码已从调度路径中移除。 -唯一的改动是抢佔代码有经过编译修正。 -在新版本抢佔设计的准备过程中,旧代码已经在 [YUNIKORN-1269](https://issues.apache.org/jira/browse/YUNIKORN-1269) 被删除。 - -为了帮助关键的工作负载顺利运行,抢占几乎是所有调度程序都会使用的功能。 -抢佔的重要性来自系统没有这个功能就无法顺利运行的事实,例如 k8s 上的 DaemonSets,以及其他像 SLA 或优先级等因素。 -DaemonSet pod 的抢占已作为 [yunikorn-1085](https://issues.apache.org/jira/browse/YUNIKORN-1085) 的一部份实现,因此,本设计着重在其他工作负载的抢占。 - -## 目标 - -* 重用现有的 Kubernetes 对象 -* 实现队列间抢占 -* 使用核心调度器中的优先级资讯支援抢佔功能 - -## 非目标 - -* 队列内抢占 -* 跨节点抢占 -* 支援所有的优先级 - -## 抢佔与优先级 - -### Kubernetes - -整个集群中,所有命名空间内的所有 Pod 都会根据优先级进行排序。 -相较于优先级低的 Pod,优先级高的 Pod 会先被进行调度。 -Kubernetes 调度程序中的抢占也仅基于这种优先级。 -完整的文档可以在[这里](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/) 找到。 - -关于调度顺序和抢占行为的基本原理是:具有较高优先级的 Pod 比具有较低优先级的 Pod 更重要。 -这个是跨命名空间的,且没有任何限制。 -具有较高优先级的 Pod 会更早地被调度,并可能触发另一个命名空间的 Pod 的抢占。 - -Pod 的规范中定义了优先级。 -优先级是一个数字,在规范中通过 PriorityClass 对象被引用。 -该对象定义了一个优先级,并将其映射到一个值。 -在较新的版本(Kubernetes 1.24 或更高版本)中,PriorityClass 还包含调度阶段的抢占策略。 -此 preemptionPolicy 仅允许 Pod 在调度阶段可以选择不抢占其他优先级较低的 Pod。 -它无法在 Pod 运行时改变抢占行为,也不是为此而设计的。 - -当节点上的 kubelet 驱逐 Pod 时,也会使用 Pod 优先级。 -例如,如果节点超载,或者内存或 CPU 耗尽,节点就会开始驱逐 Pod。 -这些驱逐有助于保持节点稳定,考虑驱逐的 Pod 对象则会根据优先级和其他一些因素进行排序。 - -### YuniKorn - -Kubernetes 中的行为集中在调度周期上。 -如果从批次处理,或资料处理工作负载的角度来检视抢占,我们需要考虑到在运行过程中退出的可能性,不过目前工作负载的配置中没有这一选项。 - -简单的抢占方法符合 Kubernetes 设计用于服务类工作负载的要求。 -服务可以处理底下的 Pod 被抢佔之后所触发的扩容或缩容。 - -但 Spark 的情况并非如此。 -驱动器(driver)的 Pod 会管理这个工作底下其他的 Pod。 -当驱动器被抢占时,整个工作都会受到影响。 -抢占驱动器会产生后续影响,导致多个 Pod 从群集中被删除,对于大型工作而言,这可能意味着数百个 Pod。 -由于这种情况的影响远大于抢佔其他单个 Pod,因此需要尽可能避免抢占驱动器或初始化启动器的 Pod 。 - -我们需要考虑的另一种情况是:在集群上运行的互动式会话。 -这种互动式会话(例如 python notebook)是一次性实例,重新启动会产生重大影响。 -因此,抢占这样的实例也不是个理想的结果。 - -要知道去避免抢佔哪个 Pod 的系统是很困难的,甚至是不可能的。 -在这种情况下,Pod 上设置需要设定「禁止抢占」的标记。 -设计方案将在 Pod 规范中讨论此选项。 - -### 优先级限制 - -在 Kubernetes 集群中,PriorityClass 对象定义了优先级,它是集群层级的物件。 -集群管理员会定义对象,因此也定义了支援的优先级。 - -Pod 上可设置的优先级没有限制。 -提交 Pod 时,唯一的检查是:是否定义了 Pod 规范中的 PriorityClass。 -任何恶意用户都可以创建具有最高优先级的 Pod。 - -限制优先级是可能的,但需要 API 服务器标记,而这很难在公共云环境中被支援。 -在 YuniKorn 调度的集群中,我们无法依赖该选项。 - -## 抢占法则 - -在 Apache YARN 调度器中实施抢占的先验知识被用于创建本设计。 -它构成了「抢占法则」的基础。 -这些法则描述了整体抢占行为。 - -YuniKorn 的抢占基于分层队列模型,以及和分配给队列的资源保证。 - -抢占被用来使队列的使用率至少达到其保证的资源容量,但它不能保证每个队列都能获得这个目标,某些情况下会无法达到这种状态。 -因此,抢占并不能保证会到达最终的最佳状态。 -通常队列的最终状态会接近保证的资源容量。 - -无法达到最佳状态的一个例子是:一组队列的保证资源总和大于群集中当前可用的资源。 -这就不可能让所有队列都获得其保证资源量。 -类似情况还有很多,例如在分层结构中,最大配额设置在层级结构中的某一点,从而无法达到最佳状态。 - -下面提供了规则概述,之后会对每条规则进行详细解释: - -1. 抢佔政策只是强列建议,没有任何保证 -2. 抢占不会使队列的容量低于其保证容量 -3. 一个任务不能抢占同一应用中的其他任务 -4. 除非一个任务的队列低于其保证容量,否则任务不会触发抢占 -5. 除非任务队列超过其保证容量,否则底下的任务不能被抢占 -6. 任务只能抢占优先级较低或相同的任务 -7. 任务不能抢占其抢占范围外的任务(单向限制) - -围绕任务和队列给出的大多数规则都是为了防止抢占风暴或循环抢佔。 -可能引发后续抢占的行为应该被避免,上述规则应保证不会出现这种情况。 -违反规则可能会在调度或应用程序运行期间导致不可预测的行为。 - -### 抢占策略只是强烈建议,没有任何保证 - -Pod 可以请求不被抢占,但这并没有受到保证。 -在某些情况下,调度程序仍有可能抢占 Pod。 -如果没有其他解决方案,这会是最后的手段。 -这意味着抢占策略只是一种强烈的提议,而不是保证。 - -DaemonSet 就可能打破规则,并抢占选择退出抢占规则的 Pod 。 -DaemonSet Pod 必须在指定节点上运行。 -如果该节点上运行的所有 Pod 不是 DaemonSet Pod,就是选择不能被抢占的 Pod 时,在没有其他选择的情况下,即使是选择不能被抢占的 Pod 也会被抢占。 - -### 抢占永远不会使队列的容量低于其保证容量 - -从抢占角度看,队列上配置的保证资源容量是队列的最佳资源配置。 -由于抢占试图让队列获得其保证资源,如果允许让抢占将队列的资源减少到其保证容量以下,就会触发新一轮的抢占。 - -当一个任务被考虑成为抢占受害者时,从队列中移除该任务后,队列的使用量不得低于其保证资源容量。 -如果删除任务会使队列低于其保证资源容量,该任务就不能成为候选人。 - -这可能意味着,即使队列高于其保证资源容量,也不允许抢占队列中的任何任务。 - -### 不能抢占同一应用程序中的其他任务 - -作为当前设计的一部分,我们只实施队列间抢占。 -此规则不适用于队列间抢占。 -在此特别记录是为了使其在不修改规则的情况下进行扩展,使得队列内抢占成为可能。 - -触发抢占的任务和被抢佔的任务不能来自同一应用程序。 - -### 除非任务队列低于其保证容量,否则无法触发抢占 - -抢占试图让队列至少获得其保证资源。 -允许已超过其保证资源容量的队列中的任务进行抢占无助于实现这一目标。 - -抢占不是使队列达到最大资源容量的工具。 -因此,在这种情况下不允许队列中的任务触发抢占。 -正常调度将处理超出其保证容量的队列的资源分配。 - -### 除非队列超过保证容量,否则底下的任务不能被抢佔 - -这是防止队列低于其保证容量的规则扩展。 -如果队列资源已低于其保证容量,则不能考虑抢占该队列正在运行中的任务。 -该队列可以触发其他队列任务的抢占。 -允许从低于保证容量的队列中删除更多资源,将导致队列更加远离其理想使用情况。 - -### 任务只能抢占优先级较低或相同的任务 - -这条规则与 Kubernetes 的默认抢占行为有关。 -不过与 Kubernetes 的规则略有不同,Kubernetes 只允许 Pod 抢占优先级较低的 Pod,而不允许抢占优先级相同的 Pod。 - -在 YuniKorn 中,抢占的应用范围稍广,因为我们用它来允许队列使用被保证的资源容量。 -两个不同队列中,具有相同优先级的 Pod 被允许相互抢占。 -如果没有优先级相同情况的抢佔规则,重新分配将变得缓慢而困难。 - -### 任务不得抢占范围之外的任务 - -这是一个特别用于多租户的规则。 -YuniKorn 允许在队列上设置抢占范围,限制可以被考虑进行抢占的任务。 -只有当任务运行在位于抢占范围内的队列上时,才能抢占另一个任务。 -关于抢占范围的更多信息如下。 - -## 抢占范围 - -在运行多租户工作负载的集群中,不应允许抢占一个租户的工作负载,并将资源分配给另一个租户。 -这里的租户不一定是一个公司,也可以是同一公司内的一个部门或业务组。 -租户映射到队列层次结构,队列层级结构可以跨越租户限制。 - -我们将这一点转化为 YuniKorn 的视角:让抢占行为仅限于队列层级结构的一部分是可能的。 -为此,我们希望引入抢占范围的概念。 -抢占范围是队列上的设置,用于阻止抢占动作检视范围外的队列。 - -抢占范围可以在层级结构上任何队列、任何位置进行设置。 -在查找抢佔的受害者时,它会阻止向上遍历。 -抢占范围是单向的,它阻止向外(即向队列层级结构的更高层)移动,但不会阻止向内(或向下)移动。 -下面的示意图呈现了一个应用抢占范围的示例: - -![preemption fencing](./../assets/preemption_fence.png) - -该示例定义了三个不同级别的抢占范围。箭头描述了抢占流程。 - -首先看`队列 A`。 -抢占范围是在叶队列上定义的,这意味着抢占被限制在该队列内。 -这会限制`队列 A`进行队列间的抢占。 -因此,抢佔只能发生在队列内,但这在当前的设计中是被排除的。 -所以最终不会实现队列内抢佔的例子,不过我们允许这种配置。 - -第二个抢占范围设置在`租户 1`的级别。 -这个抢占范围会影响`队列 B`中运行的任务。 -`队列 B`中的任务可以在`租户 1`队列下方的所有队列找到抢占的受害者(在示意图中用 _黄色_ 箭头表示)。 - -对于`租户 2`队列也创建了类似的设置。 -在这种情况下,`队列 1`和`队列 2`之间可以相互抢占(在示意图中用 _蓝色_ 箭头表示)。 - -在`租户 1`或`租户 2`队列下方的队列中的任务都不能抢占`系统队列`中的任务。 -`系统队列`中的任务没有被设定抢占范围。 -这意味着在示意图中,`系统队列`中的任务可以检查层级结构中的任何队列(如 _红色_ 箭头所示)。 - -## 抢占逻辑 - -要触发默认的 Kubernetes 调度程序进行抢占,Pod必须适应任何命名空间的配额,且找不到能分配该 Pod 的节点。 -抢占会尝试找到一个节点来运行该 Pod,并专注于节点。 -节点上所有具备较低优先级的 Pod 都被视为抢占的候选对象。 -调度程序会减少候选对象的受害者列表,直到差不多足以容纳新 Pod。 - -调度程序会从触发抢占的 Pod 中,追踪进行抢占的节点。 -出于多种原因,它不能保证触发抢占的 Pod 会被调度到抢占的节点上。 - -从 YuniKorn 的角度来看,我们已经为 DaemonSet 类型的 Pod 实现了以节点为重点的抢占。 -来自 DaemonSet 的 Pod 必须在特定节点上运行,抢占的重点是为该节点腾出空间。 -YuniKorn 保证该 Pod 将在该节点上运行,且直到 DaemonSet 的 Pod 被调度前,节点上没有任何 Pod 会被调度。 - -YuniKorn 中通用的抢占行为与其保证队列的保证配额有关(**规则 4**)。 -只有在延迟之后才会触发抢占。 -在触发抢占之前,必须至少经过一个抢占延迟单位。 -与其查找节点不同,寻找受害者的第一步是基于其保证配额已用尽的队列构建受害者列表(**规则 5**)。 -如果找不到在抢占范围内的队列(**规则 7**),抢占会立即停止。 - -下一步是构建受害者列表,这可能来自一个或多个队列。 -若优先级高于触发抢占的 Pod,则该 Pod 会被忽略(**规则 6**)。 -接着会忽略大于超额配额部分资源量的 Pod(**规则 2**)。 -当决定要抢占哪些受害者时,可能会考虑受害队列在层次结构中,与触发抢占的队列的接近程度。 -具体细节将在实施阶段中解决。 - -跨节点抢占是不支援的,被抢占的受害者们必须运行在同一节点上。 -每个节点上的受害者们会被分组。 -一组受害者,结合节点上可分配的空间,将决定该组是否可行。 -在开始抢占之前,必须进行检查以确保进行抢佔的 Pod 能适应该节点。 -如果有多个可行的组,则需要进行选择。 -如何选择组的逻辑是一个实现细节。 - -在选择了一组受害者并间接选择了一个节点后,该节点将为 Pod 保留。 -会根据受害者列表触发抢占,并在完成后将 Pod 调度到节点上。 -保留动作会保证将触发抢佔的 Pod 被调度到该节点。 -一个副作用是,重新启动被抢占的 Pod 后,这些受害者不能回到被释放的空间中,调度程序会等待所有被抢占的 Pod 退出。 -它们可以被调度到不同的节点上,这不会阻止触发抢占的 Pod 被调度。 - -## 防止抢占循环 - -抢佔规则防止了循环抢占。应添加测试来复盖每个规则和以下情况。 - -ReplicaSet 是防止出现循环和循环抢占的良好示例。 -每次从副本集中移除一个 Pod 时,ReplicaSet 控制器都会创建新的Pod,以确保集合完整。 -如果规则未正确复盖所有情况,这种自动重新创建可能会触发循环。 -标准测试的一部分应考虑涵盖以下的情况。 - -范例设置:Replica set _Prod Repl_ 在队列 _Prod_ 中运行。为了测试,一个 Replica set _Test Repl_ 在队列 _Test_ 中运行。这两个队列都属于相同的父队列(它们是同级的)。 -这些Pod都使用相同的优先级和抢占设置。集群中没有剩馀空间。 - -基本范例 1:_Prod_ 位于其保证配额内,且多个 Replica set 的 Pod 被搁置。 -_Test Repl_ 集合的所有 Pod 都在运行,且 _Test_ 超过了其保证资源容量。 - -抢占情形 1:为了为 _Prod Repl_ 创建一个 Pod 的空间,会抢占 _Test Repl_ 中的一个Pod。 -两个队列最终都会超过其保证资源容量。 -_Test Repl_ 中的Pod将被重新创建。它不能抢占 _Prod Repl_ 中的 Pod,因为那会导致 _Prod_ 队列低于其保证资源容量。 -_Test Repl_ 中的Pod将不得不等待,直到集群中有空间可用。 -_Prod Repl_ 的其他Pod也必须等待,由于 _Prod_ 队列已经超过了其保证资源,将无法再触发抢占。 - -抢占情形 2:尽管 _Test_ 超过了其保证资源容量,如果抢占了一个 _Test Repl_ 的 Pod,它最终会低于保证资源容量,因此不会触发抢占。 -_Prod Repl_ 的 Pod 将保持搁置,直到集群中有可用空间。 - -抢占情形 3:为了帮 _Prod Repl_ 创建一个 Pod 的空间,会抢占 _Test Repl_ 中的一个 Pod。 -_Prod_ 队列即使有额外的 Pod,仍然低于其保证资源。 -_Test Repl_ 集合中的 Pod 将被重新创建。 -由于 _Prod_ 仍然低于其保证资源,它不会被当成受害者。 -_Test Repl_ 中的 Pod 必须等待到集群中有空间可用,而 _Prod_ 队列可以触发更多的抢占。 -抢占检查会从头开始,这可能会触发 0 次或多次从 _Test_ 队列的抢占,具体情形取决于实际状态。 - -## 抢占配置 - -### 优先级类 - -作为 Pod 规范的一部分,我们需要提供禁止抢占的方式。 -如果允许用户独立于优先级规则,在 Pod 上进行禁止抢占的设定,会导致 Kubernetes 和 YuniKorn 的抢占配置不一致。 -这还会使得群集管理员失去定义哪些优先级不应该被排除的管理权。 - -一个设计目标是不在 Kubernetes 中引入新的物件。 -考量上述提到在集群级别中,关于禁止抢占的控制和管理,这个设计重用了现有的 PriorityClass 对象。 -我们不能也不该破坏默认的 Kubernetes 调度程序的现有功能,且插件版本会依赖于默认调度程序及其行为。 -Pod 将像标准 Kubernetes 一样使用 priorityClassName。 - -PriorityClass对象允许指定一个 _preemptionPolicy_,这有两个可能的值: -* PreemptLowerPriority -* Never - -这些值是在核心类型和验证中硬编码的。 -除非对 Kubernetes 进行更改,否则无法添加新的值。 -这意味着不能重新使用 _preemptionPolicy_ 属性本身。 -该属性的内容将被传播到调度核心,让 YuniKorn 在调度时考虑此设置。 - -与 Kubernetes 中的其他所有对象一样,PriorityClass 对象扩展了基本对象,包括元数据。 -作为元数据的一部分,我们可以在对象上设置标签或注释。 -在我们添加的所有扩展中,标签比注释更受到限制。 -一般情况中,我们倾向于在扩展中使用注释而不是标签。 - -我们的提议是在 PriorityClass 上添加一个注释,标示禁止抢占。 -注释的名称将遵循我们用于所有其他注释的相同结构: -yunikorn.apache.org/allow-preemption - -作为注释值,这里建议使用布尔值: - -* "true":允许被抢占 -* "false":不允许抢占 - -如果没有设置 _allow-preemption_ 的值,则将使用默认值 _true_。 - -这个设计要特别注意。 -将注释的值设置为 _false_ 表示 Pod 可能会请求不被抢占。 -但这不是一个保证。 -如果没有其他解决方案可用,调度程序仍然可能会抢占 Pod,这将是最后手段。 -这意味着上面定义的抢占策略只是强烈的提议,而不是一个保证。 - -可能会打破规则,抢占一个将注释设置为 _false_ 的 Pod 的示例是 DaemonSet。 -DaemonSet Pod必须在指定的节点上运行。 -如果在该节点上运行的所有 Pod 都是其他DaemonSet Pod 或 _allow-preemption_ 设置为 _false_ 的 Pod,那么在没有其他选择的情况下,选择禁止抢占的 Pod 还是会被抢占。 - -### 应用程序设置 - -优先级是 Kubernetes 上的 Pod 规范的一部分。 -每个 Pod 都会被 k8shim 转换为 AllocationAsk 对象。 -[YUNIKORN-1085](https://issues.apache.org/jira/browse/YUNIKORN-1085) 中实现了一部份的 DaemonSet 抢占,Pod 的优先级被读取,并设置到创建的 AllocationAsk 上。 -目前传递的优先级只是一个普通的整数值,我们也不需要更多。 - -作为抢占的一部分,我们需要传递两个额外的附加值。 -这两个值一起组成了 YuniKorn 的抢占策略。 -这些值是 Kubernetes shim 发送的 AllocationAsk 中的一部分,并被传递到核心,两个值都映射到上述 PriorityClass 的内容。 -与其添加两个单独的栏位,把它们封装到一条新消息中更清楚。 - -抢占策略可针对任何 AllocationAsk 进行处理,即使它有消息中的 "Originator" 标志设置为 _false_。 -指定不同的抢占行为可能很重要,这会使得请求抢占的成本低,而选择退出抢佔的成本相对高。 - -使用案例还是 Spark 应用程序。一般会希望 driver 退出抢佔流程,而其他 Pod 则可以在调度期间进行抢占。 - -以 protobuf 消息的形式显示如下: - -``` -message AllocationAsk { - ... - // The preemption policy for this ask - PreemptionPolicy preemptionPolicy = 12; -} - -message PreemptionPolicy { - // Allow preemption while running - // Based on the YuniKorn annotation from the PriorityClass object - bool allowPreemption = 1; - // Preemption behavior while scheduling - // Based on the K8s preemptionPolicy from the PriorityClass object - string schedulerPreemption = 2; -} -``` - -### 队列配置 -在队列配置对象中会添加两个新属性,以指定抢占范围类型和抢占延迟。 -`preemption.policy` 和 `preemption.delay` 这两个属性可以作为队列的一部份,在任何队列上设置。 -如下所示: - -```yaml -queues: - - name: fencedqueue - properties: - preemption.policy: fence - preemption.delay: 30s -``` - -子模板中完全支援这些属性。 -现有的功能中支援为动态队列设置这些属性。 - -根队列上可以设置 _preemption.policy_ 属性,但不会有任何作用。 -根队列作为层级结构的顶层,没有父队列,这意味着抢占无法在队列树的更上层执行。 -如果 _preemption.policy_ 设置在根队列上,则不会有任何记录。 - -支援的 _preemption.policy_ 值有 -* default -* fence -* disabled - -如果在队列上设置了 `fence`,则设置了该属性的队列或底下的下层队列中,不能抢占队列树外的其他任务。 -默认值 `default` 不会将抢占范围限制在子树上。 -如果没有设置抢佔策略 则使用 `default` 值。 - -_preemption.delay_ 只能在叶队列上设置。 -叶队列包含任务,当队列低于其保证资源容量时,任务才会触发抢佔。 -在非叶队列上设置抢占延迟则不会有任何影响,如果父队列上设置了 _preemption.delay_,则不会记录任何信息。 - -_preemption.delay_ 值必须是字符串形式的有效 Golang 时间长。 -该值将使用时间包中定义的 `ParseDuration` 。 - -如果指定了 _preemption.delay_,其值必须大于 `0s`。如果没有指定 _preemption.delay_ 属性,则使用默认的 `30s`。 -如果字符串解析失败,一样使用 `30s`。 - -## 调度器存储物件更改 - -### AllocationAsk - -根据通讯的变化,调度器中的对象也需要修改,以永久话记录一些通信细节。 -对于 AllocationAsk,我们需要存储两个新属性。 - -建议的新属性:_allowPreemption_ 和 _schedulerPreemption_ - -- _schedulerPreemption_ 仅在调度阶段使用 -- _allowPreemption_ 将被传送到下方定义的 Allocation - -### Allocation - -基于 AllocationAsk 创建的分配(Allocation)需要一个新属性。 -这消除了检查底层 AllocationAsk 是否允许抢占的需要。 -分配中不需要调度程序的抢占值。 - -建议的新栏位:_allowPreemption_ - -### 队列 - -新的抢占策略和延迟值需要存储在队列对象中。 -配置对象不会发生更改,因为我们在配置中使用队列属性来存储它们。 - -建议的新属性:_preemptionPolicy_ 和 _preemptionDelay_ diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/design/scheduler_plugin.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/design/scheduler_plugin.md deleted file mode 100644 index 6656625d099..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/design/scheduler_plugin.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: scheduler_plugin -title: K8s 调度器插件 ---- - - - - -## 背景 - -在 Kubernetes 上,原始的作法是将 YuniKorn 当作 Kubernetes 调度器从零开始实现的。这使我们能够快创新,但也存在问题。我们目前有许多地方 -调用非公开的 K8S 源代码API,这些API的稳定性各不相同,当我们切换到新的 Kubernetes 版本时,需要进行破坏性的代码更动。 - -理想情况下,我们应该能够自动地支援新的 Kubernetes 发布版本,并受益于新功能。使用插件模式可以增强 Kubernetes 版本的兼容性,减少工作量。 -此外,在许多情况下,允许非批次处理工作负载绕过 YuniKorn 调度功能并使用默认调度逻辑是可取的。然而,我们目前无法做到这一点,因为 -YuniKorn 调度器二进制文件中没有默认的调度功能。自 Kubernetes 1.19 版本以来,Kubernetes 项目已经创建了一个稳定的 API -用于[调度框架](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/), -允许创建实现各种扩展点的插件。插件实现一个或多个这些扩展点,然后编译为调度器的二进制文件,其中包含默认调度器和差件代码, -并在正常调度流程中调用插件。 - -## 设计 - -我们在 k8s-shim 代码库中添加了一个调度器插件,可以用来编译为 Kubernetes 调度器,其中包含 YuniKorn 功能以及默认调度器功能。 -显著地提高 YuniKorn 与 Kubernetes 的兼容性,并有更大的信心将 YuniKorn 部署为集群中唯一的调度器。将为调度器建构分别两种 Docker 镜像: -传统的 YuniKorn 调度器构建为 `scheduler-{version}`,而新的插件版本构建为 `scheduler-plugin-{version}`。可以通过自定义调度器镜像 -来交替部署它们到 Kubernetes 集群中,使用相同的 Helm charts 进行部署。 - -## 入口点 - -现有的 shim `main()` 方法已经被移动到 `pkg/cmd/shim/main.go`,并创建了一个新的 `main()` 方法在 -`pkg/cmd/schedulerplugin/main.go` 之下。该方法实例化默认的 Kubernetes 调度器,并将 YuniKorn 作为一组插件添加到其中。 -它还修改了默认调度器器的 CLI 参数解析,以添加 YuniKorn 特定的选项。创建 YuniKorn 插件时,它将在后台启动现有的 shim / core 调度器, -同步所有的 informer, 并启动正常的 YuniKorn 调度循环。 - -## Shim 调度器更改 - -为了与默认调度器合作,当处于插件模式时,shim 需要稍微不同地操作。这些差异包括: - -- 在 `postTaskAllocated()` 中,我们实际上不会绑定 Pod 或 Volumes,因为这是默认调度器框架的责任。 - 相反,我们在内部映射中跟踪 YK 为节点分配的节点,分派一个新的 BindTaskEvent,并在 Pod 上记录一个 `QuotaApproved` 事件。 -- 在 `postTaskBound()` 中,我们将 Pod 的状态更新为 `QuotaApproved`,因为这将导致默认调度器重新评估 Pod 的调度(更多细节见下文)。 -- 在调度器缓存中,我们跟踪待处理和进行中的 Pod 分配。当 Pod 在 Kubernetes 中被删除时,也将调度器缓存中的 Pod 删除。 - - -## 插件模式的实现 - -为了暴露 YuniKorn 的全部功能,我们实现了三个调度框架插件: - -### PreFilter - -PreFilter 插件被传入一个 Pod 的引用,并根据是否应该考虑该 Pod 进行调度,返回 `Success` 或 `Unschedulable`。 - -对于 YuniKorn 的实现,我们首先检查 Pod 是否定义 `applicationId`。如果没有,我们立即返回 `Success`, -这允许我们将非批处理工作负载委托给默认调度器。 - -如果存在 `applicationId`,则确定是否存在待处理的 Pod 分配(表示 YuniKorn core 已经决定分配该 Pod)。 -如果存在待处理的 Pod 分配,我们返回 `Success`,否则返回 `Unschedulable`。 -此外,如果检测到正在进行的分配(表示我们先前尝试过调度该 Pod),我们触发一个 `RejectTask` 事件给 YuniKorn core, -以便稍后重新发送该 Pod 进行调度。 - -### Filter - -Filter 插件用于过滤无法运行 Pod 的节点。只有在 PreFilter 阶段通过的 Pod 才会进行评估。 - -对于 YuniKorn 插件,我们遵循类似 PreFilter 的逻辑,但我们还验证「待处理的 Pod 分配」之节点是否与 YuniKorn 选择的节点匹配。 -如果节点匹配,我们将待处理分配转换为进行中的分配。这样做的目的是确保与默认调度器保持同步。因为有可能我们允许分配继续进行, -但由于某些原因导致绑定失败。这样的处理方式有助于保持一致性。 - -### PostBind - -PostBind 扩展点在信息上用于通知插件一个 Pod 已成功绑定。 - -YuniKorn 使用这个来清理未完成的Pod分配进程。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/design/simple_preemptor.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/design/simple_preemptor.md deleted file mode 100644 index 7dbce187c71..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/design/simple_preemptor.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -id: simple_preemptor -title: DaemonSet Scheduling using Simple Preemptor ---- - - -# Design & Implementation of Preemption for DaemonSet Pods using Simple Preemptor - -The simplistic approach to preempt or free up resources of running applications for DaemonSet pods. A good example of daemonset pod is fluentd logging pod which is very essential for any applicaton pod running in the node for logging. - -## When to start preemption? -[YUNIKORN-1184](https://issues.apache.org/jira/browse/YUNIKORN-1184) ensures daemon set pods have been allocated properly if resources are available on the required node, otherwise, reserve the same required node so that it can be picked up to make reservation as reserved allocation (AllocatedReserved) in the next scheduling cycle. However, the whole process of modifying the reservation to reserved allocation depends on how much resources are freed up in the meantime. Duration for freeing up resources by natural course is non deterministic as it depends on the running pods execution on that particular node and it could take slightly longer time as well. - -By any chance, before the next run of the regular scheduling cycle (context#schedule() ), resources become available and particularly on that specific required node, then nothing needs to be done. It just moves ahead with the next steps. In case of resource constraints, unlike the regular pod reservation, other nodes cannot be tried by calling application#tryNodesNoReserve() as this demonset pod needs to run only on the specific required node. Instead, we can fork a new go routine (trigger_preempt_workflow() ) to run the workflow steps described below. - - -## How to do preemption? -K8s does the preemption based on the pod priority. Pods with lower priority would be chosen first and so on. Proposal is not to depend on k8s for Preemption. Instead, Core should take the responsibility of finding out the list of pods that needs to be preempted, making communications to Shim and finally expecting the preempted resources to allocate to the corresponding daemonset automatically as part of the regular scheduling cycle. - -### Steps in trigger_preempt_workflow() go routine: - -##### Reservation age check (1) -We can introduce a new Reservation age “createtime” (can be added to the reservation object) to check against the configured value of preemption_start_delay, a property to define the minimal waiting time to start the preemption process. Once reservation age exceeds this waiting time, the next step would be carried out. Otherwise, the corresponding reservation has to wait and can be processed next time. - -##### Get allocations from specific required Node (2) -Get all allocations from the required node of the daemonset pod and go through the below Pre-filter pods step to filter the pods not suited for a preemption. - -##### Pre-filter pods to choose Victims/Candidates suited for Preemption (3) - -Core should filter the pods based on the following criteria: - -###### DaemonSet Pods - -All Daemonset pods should be filtered out completely irrespective of priority settings. Depending on the “requiredNode” value of pod spec, these pods can be filtered out and cannot be taken forward for the remaining process. - -![simple_preemptor](./../assets/simple_preemptor.png) - -##### Ordering Victim pods (4) - -###### Pods classification - -Once pods has been filtered out, need to classify the pods based on its types: - -1. Regular/Normal Pods (RP) -2. Driver/Owner Pods (DP) -3. Preemption Opt out Pods (OP) - -This classification ensures different treatment for each type of pod so that victims can be chosen among these pods in the same order. Please refer to the above diagram. It shows the 2-Dimensional array (NOTE: “Array” has been used only for documentation purposes, need to finalize the appropriate data structure) with each sub array holding pods of the same type. 1st sub array has RP’s, 2nd sub array has DP’s, 3rd sub array has OP’s and goes on. - -Regular/Normal Pods (RP) - -The regular/normal pods should be gathered and placed in the 1st sub array as these pods are given first preference for choosing the victims. In general, preempting these pods have very little impact when compared to other types/classes of pods. Hence, keeping these pods in the first subarray is the right choice - -Application Owner (DP) - -Pod acting as owner/master for other pods in the same application should be placed in the 2nd sub array because preempting those kinds of pods has a major impact when compared to Regular pods. We can select these pods by checking whether any owner reference exists between this pod and other pods. This will help prevent scenarios such as a driver pod being evicted at a very early stage when other alternatives are available for choosing the victim. - -Preemption Opt out (OP) - -Pods can be allowed to run with the Preempt opt out option. So, Pods marked with opt out should be placed in the 3rd sub array and can be used to choose victims as a last option. For now, we can use a label such as yunikorn.apache.org/allow-preemption: false for detecting those pods. - - -As and when we want to introduce a new class/type of Pods, a new sub array would be created for the same and would be placed in the main array based on its significance. - -###### Sorting Pods - -Each sub array should be sorted based on the multiple criteria: - -1. Priority -2. Age -3. Resource - -Each sub array would be sorted priority wise, age wise and finally resource wise. The 1st sub array carrying Regular Pods has 4 pods of priority 1 and 2 pods of Priority 2. Among the 4 pods of the same priority, 3 pods are of the same age as well. Hence, again sorting resource wise really adds value and sorts them in the above shown order. Please refer to “zone”. - -#### Victim pods selection strategy (5) - -Introduce a new configuration, preemption_victim_poselection_strategy with different options (single, multiple etc) but later options act as fallback to earlier one. Defining an order for these options should be possible and upto the Administrator to place the options in an order he/she desires. Depending on the values, the whole selection strategy mechanism can decide whether a “fallback” approach among these options should be followed or not. Depending on the value, the selection strategy process would continue with the next option only if no selection has been made with the earlier option or stop only with the first option even if no selection has been made. - -##### 1. Single Victim Pod - -Single Victim Pod, but resource deviation between victim pod and daemonset pod is not beyond configurable percentage. Configuring deviation with lower percentage (for example, 5% or 10%) helps prevent evicting victim pods already running with higher resource requirements. If there are many single victims found within the defined deviation %, then selection starts based on deviation % ascending order as intent is to choose the victim as close as possible to the daemonset pod resource requirements. - -##### 2. Multiple Victim Pods - -Multiple Victim Pods, but no. of victim pods not more than configured value. This selection strategy helps to choose more than one victim, starts with the victim (resource wise descending order) and goes upto to a stage where total resource of victims meets the daemonset resource requirements but ensuring total count of victim pods not exceeding configured value. - -New config: preemption_victim_pods_selection_strategy -Possible values are single,multiple (default) or multiple,single or single or multiple - -In case of more than one value (for ex. single,multiple), fallback would be followed as described above. - -#### Communicate the Pod Preemption to Shim (6) - -Once the list of pods has been finalized for preemption, Core can make a call to Shim for termination using notifyRMAllocationReleased (with type as TerminationType_PREEMPTED_BY_SCHEDULER). Shim can process the request as usual by making a call to K8s to delete the pod and subsequently call failTaskPodWithReasonAndMsg to notify the pod with reasons. - -### What happens after Preemption? - -Shim makes a call to K8s to delete the pod. Once k8s delete the pod, shim gets a notification from k8 and passes the information to core. This flow happens for any pod deletion and exists even today. So, even for preempted resources, we can leave it upto the regular scheduling cycle and Core-Shim communications to allocate these freed up preempted resources to the daemonset pod as node has been already reserved much earlier before the above described whole preemption workflow has begun. \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/build.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/build.md deleted file mode 100644 index c1e3803819a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/build.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: build -title: 建构和运行 ---- - - - -YuniKorn始终与容器编排系统一起使用。目前,在我们的存储库中提供了一个Kubernetes适配器[yunikorn-k8shim](https://github.com/apache/yunikorn-k8shim),您可以利用它来开发YuniKorn调度功能并与Kubernetes集成。本文档描述了如何设置开发环境以及如何进行开发。 - -## 开发环境设置 - -首先阅读[环境设置指南](developer_guide/env_setup.md)以设置Docker和Kubernetes开发环境。 - -## 为Kubernetes构建YuniKorn - -先决条件: -- Golang: 在存储库的根目录中检查 `.go_version` 文件以获取Yunikorn所需的版本。最低版本可能会根据发布分支而变化。较早的Go版本可能会导致编译问题。 - -您可以从 [yunikorn-k8shim](https://github.com/apache/yunikorn-k8shim) 项目构建用于Kubernetes的调度器。 -构建过程将所有组件构建为一个可部署并在Kubernetes上运行的单个可执行文件。 - -通过拉取 `yunikorn-k8shim` 存储库来启动集成构建过程: -```bash -mkdir $HOME/yunikorn/ -cd $HOME/yunikorn/ -git clone https://github.com/apache/yunikorn-k8shim.git -``` -此时,您已经拥有一个允许您构建YuniKorn调度器的集成映像的环境。 - -### 关于Go模块和Git版本的说明 -Go使用Git来获取模块信息。 -如果用于构建的计算机上安装的Git版本较旧,可能无法检索某些模块。 -当首次尝试构建时,可能会记录类似于下面的消息: -```text -go: finding modernc.org/mathutil@v1.0.0 -go: modernc.org/golex@v1.0.0: git fetch -f origin refs/heads/*:refs/heads/* refs/tags/*:refs/tags/* in : exit status 128: - error: RPC failed; result=22, HTTP code = 404 - fatal: The remote end hung up unexpectedly -``` -要解决此问题,请将Git更新到较新的版本。 -已知Git版本1.22或更高版本可以正常工作。 - -### 构建Docker镜像 - -可以通过以下命令触发构建Docker镜像。 - -``` -make image -``` - -带有内置配置的镜像可以直接部署到Kubernetes上。 -可以在 [deployments](https://github.com/apache/yunikorn-k8shim/tree/master/deployments/scheduler) 目录下找到一些示例部署。 -对于使用ConfigMap的部署,您需要在Kubernetes中设置ConfigMap。 -如何使用ConfigMap部署调度器在 [scheduler configuration deployment](developer_guide/deployment.md) 文档中有详细说明。 - -镜像构建命令首先会构建集成可执行文件,然后创建Docker镜像。 -如果您想使用基于发布的预构建镜像,请检查 [Docker Hub repo](https://hub.docker.com/r/apache/yunikorn). - -默认的镜像标签不适用于部署到可访问存储库,因为它使用了硬编码的用户并且会使用正确的凭据推送到Docker Hub。 -您必须更新`Makefile`中的`TAG`变量以推送到可访问存储库。 -在更新镜像标签时,请注意,所提供的部署示例也需要相应更新以反映相同的更改 - -### 检查 Docker 镜像 - -之前构建的Docker镜像包含了一些重要的构建信息,您可以使用Docker的inspect命令来检索这些信息。 - -``` -docker inspect apache/yunikorn:scheduler-amd64-latest -``` - -`amd64`标签取决于您的主机架构(例如,对于`Intel`,它将是`amd64`,对于`Mac M1`,它将是`arm64`)。 - -这些信息包括每个组件的`git`修订版(最后的提交`SHA`),以帮助您了解此镜像中包含的源代码版本。它们以 `Docker` 镜像的`标签`形式列出,例如: - -``` -"Labels": { - "BuildTimeStamp": "2019-07-16T23:08:06+0800", - "Version": "0.1", - "yunikorn-core-revision": "dca66c7e5a9e", - "yunikorn-k8shim-revision": "bed60f720b28", - "yunikorn-scheduler-interface-revision": "3df392eded1f" -} -``` - -### 依赖关系 - -项目中的依赖关系使用[Go模块](https://blog.golang.org/using-go-modules)来管理。 -Go模块要求在开发系统上至少安装Go版本1.11。 - -如果您想在本地修改其中一个项目并使用本地依赖关系进行构建,您需要更改模块文件。 -更改依赖关系使用`replace`指令,如 [Update dependencies](#updating-dependencies)中所述。 - -YuniKorn项目有四个存储库,其中三个存储库在Go级别有依赖关系。 -这些依赖关系是Go模块的一部分,指向GitHub存储库。 -在开发周期中,可能需要打破对GitHub提交版本的依赖关系。 -这需要更改模块文件,以允许加载本地副本或从不同存储库中分叉的副本。 - -#### 受影响的存储库 -以下存储库之间存在依赖关系: - -| repository| depends on | -| --- | --- | -| yunikorn-core | yunikorn-scheduler-interface | -| yunikorn-k8shim | yunikorn-scheduler-interface, yunikorn-core | -| yunikorn-scheduler-interface | none | -| yunikorn-web | yunikorn-core | - -`yunikorn-web` 存储库不直接依赖于其他存储库的Go模块。但是,对 `yunikorn-core` 的webservices进行的任何更改都可能影响Web界面。 - -#### 进行本地更改 - -为了确保本地更改不会破坏构建的其他部分,您应该执行以下操作: -- 进行完整构建 `make`(构建目标取决于存储库) -- 运行完整的单元测试 `make test` - -应该在继续之前修复任何测试失败。 - -#### 更新依赖关系 - -最简单的方法是在模块文件中使用`replace`指令。`replace`指令允许您使用新的(本地)路径覆盖导入路径。 -不需要更改源代码中的任何导入。更改必须在具有依赖关系的存储库的`go.mod`文件中进行。 - -使用`replace`来使用分叉的依赖关系,例如: -``` -replace github.com/apache/yunikorn-core => example.com/some/forked-yunikorn -``` - -没有必要分叉并创建新的存储库。如果您没有存储库,也可以使用本地检出的副本。 -使用`replace`来使用本地目录作为依赖关系: -``` -replace github.com/apache/yunikorn-core => /User/example/local/checked-out-yunikorn -``` -对于相同的依赖关系,使用相对路径: -``` -replace github.com/apache/yunikorn-core => ../checked-out-yunikorn -``` -注意:如果`replace`指令使用本地文件系统路径,那么目标路径必须具有该位置的`go.mod`文件。 - -有关模块的更多详细信息,请参阅模块的维基页面。: [When should I use the 'replace' directive?](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive). - -## 构建Web用户界面(UI) - -示例部署引用了[YuniKorn Web用户界面](https://github.com/apache/yunikorn-web)。 -`yunikorn-web` 项目对构建有特定要求。请按照[README](https://github.com/apache/yunikorn-web/blob/master/README.md)中的步骤准备开发环境并构建Web用户界面(UI)。然而,调度器在没有Web用户界面的情况下仍然可以完全正常运作。 - -## 在本地运行集成调度器 - -在您设置好本地开发环境后,可以在本地的Kubernetes环境中运行集成调度器。 -这已在桌面环境中进行了测试,包括Docker Desktop、Minikube和Kind。有关更多详细信息,请参阅[环境设置指南](developer_guide/env_setup.md)。 - -``` -make run -``` -它将使用用户配置的配置文件,位于 `$HOME/.kube/config` 中,连接到Kubernetes集群。 - -要以Kubernetes调度器插件模式运行YuniKorn,执行: - -``` -make run_plugin -``` - -只要`$HOME/.kube/config`文件指向远程集群,您也可以使用相同的方法在本地运行调度器并连接到远程Kubernetes集群。 - -## 通过端到端测试验证外部接口更改 - -Yunikorn具有外部REST接口,由端到端测试验证。但是,这些测试存在于k8shim存储库中。 -每当对外部接口进行更改时,请确保通过运行端到端测试进行验证,或者相应地调整测试用例。 - -如何在本地运行测试的说明已经在文档中描述。[here](https://github.com/apache/yunikorn-k8shim/blob/master/test/e2e/README.md). \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/dependencies.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/dependencies.md deleted file mode 100644 index f270328664f..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/dependencies.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -id: dependencies -title: Go 模块更新 ---- - - - -## 什么时候更新 -如果调度器接口发生更改,则必须更新`master`分支中的引用。 -即使调度器接口没有改变,也可能需要更新shim的引用中,对core的依赖关系。 -可以添加依赖于消息的更改字段内容而不是消息的字段布局的新功能。在这种情况下,只需要更新shim依赖项。 - -## 为什么是伪版本 -在`master`分支中,我们**必须**对我们使用的所有 YuniKorn 存储库引用使用伪版本。 -由于该分支正在积极开发中并且尚未发布,因此我们没有真正的版本标签可供引用。 -但是,我们仍然需要能够指向依赖项的正确提交。 -Go 允许在这些特定情况下使用[伪版本](https://go.dev/ref/mod#pseudo-versions)。 -我们在 Kubernetes shim 中使用的伪版本的示例: -``` -module github.com/apache/yunikorn-k8shim - -go 1.16 - -require ( - github.com/apache/yunikorn-core v0.0.0-20220325135453-73d55282f052 - github.com/apache/yunikorn-scheduler-interface v0.0.0-20220325134135-4a644b388bc4 - ... -) -``` -发布分支**不得**使用伪版本。 -在创建版本的过程中,将创建[标签](/community/release_procedure#tag-and-update-release-for-version)。 -这些标签将用作该版本的 go.mod 文件中的参考。 - -## 伪版本的执行 -在拉取请求中,检查 `yunikorn-core` 和 `yunikorn-k8shim` 存储库强制执行版本格式。 -如果`master`分支中 `yunikorn-core` 或 `yunikorn-scheduler-interface` 存储库的版本引用不是伪版本,则会触发构建失败。 - -该检查强制版本引用的开头为`v.0.0.0-` - - -根据上面的[为什么是伪版本](#why-a-pseudo-version)解释,伪版本不会在发布分支中强制执行。 - -## 更新core依赖 -在更新core依赖项之前,必须确保调度器接口更改已完成。 -1. 在调度器界面中进行更改。 -2. 将更改提交到 GitHub 上的 master 分支并拉取最新的 master 分支提交。 -3. 为调度器接口[生成新的伪版本](#generate-a-pseudo-version)。 - -更新core依赖 - -4. 更新依赖存储库的go.mod文件:core存储库 - * 打开go.mod文件 - * 复制生成的伪版本引用 - * 将调度器接口版本引用替换为**步骤 3**中生成的版本引用 - * 保存go.mod文件 -5. 运行`make test`以确保更改有效。构建将拉取新的依赖项,并且将使用调度器接口中的更改。 -6. 将更改提交到 GitHub 上的 master 分支并拉取最新的 master 分支提交。 - -## 更新shim依赖项 -在更新 shim 依赖项之前,您必须确保core依赖项已更新并提交。 -在某些情况下,调度器接口的引用没有改变。 -这不是问题,要么跳过更新步骤,要么按照正常执行更新步骤,从而在提交过程中不会发生任何更改。 - -7. 为core[生成新的伪版本](#generate-a-pseudo-version) -8. 更新依赖存储库的go.mod文件:k8shim存储库 - * 打开go.mod文件 - * 复制生成的调度器接口的伪版本引用 - * 将调度器接口版本引用替换为**步骤 3**中生成的版本引用。 - * 复制生成的core伪版本引用 - * 将core版本引用替换为**步骤 7**中生成的版本引用。 - * 保存go.mod文件 -9. 运行`make test`以确保更改有效。构建将拉下新的依赖项,并将使用core和调度器接口中的更改。 -10. 将更改提交到 GitHub 上的 master 分支 - -:::note -如果同时在调度器接口和/或core中处理多个 PR,则不同的 PR 可能已经应用了更新。 -这完全取决于提交顺序。 -因此,执行**步骤 5**和**步骤 8**以确保不存在回归。 -::: -## 生成伪版本 - -go.mod 文件中使用的伪引用基于提交hash和时间戳。 -使用以下步骤生成一个很简单: - -1. 更改为需要生成新伪版本的存储库。 -2. 更新master分支的本地检查代码以获取最新提交 -``` -git pull; git status -``` - -状态应显示为最新的克隆位置的`origin`。 - -3. 运行以下命令获取伪版本: -``` -TZ=UTC git --no-pager show --quiet --abbrev=12 --date='format-local:%Y%m%d%H%M%S' --format='v0.0.0-%cd-%h' -``` -4. 该命令将打印如下一行: -``` -v0.0.0-20220318052402-b3dfd0d2adaa -``` -这是可以在 go.mod 文件中使用的伪版本。 - -:::note -伪版本必须基于 vcs 系统中的提交,即来自 Github 的提交。 -无法使用本地提交或尚未合并到 PR 中的提交。 -::: diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/env_setup.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/env_setup.md deleted file mode 100644 index 6881849d694..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/env_setup.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: env_setup -title: 开发环境的设置 ---- - - - -有很多种方法可以在本地设置Kubernetes开发环境,其中最常见的三种方法是`Minikube`([docs](https://kubernetes.io/docs/setup/minikube/))、`docker-desktop`和`kind`([kind](https://kind.sigs.k8s.io/) -`Minikube`通过数个虚拟机提供一个本地Kubernetes集群(通过VirtualBox或类似的东西)。`docker-desktop`能在docker容器中设置Kubernetes集群。 `kind`为Windows、Linux和Mac提供轻量级的Kubernetes集群。 - -## 使用Docker Desktop设置本地的Kubernetes集群 - -在本教程中,我们将基于Docker Desktop进行所有的安装。 -我们也可以使用轻量级的[minikube](#使用minikube设置本地的kubernetes集群)设置,它可以提供同样的功能,且需要的资源较小。 - -### 安装 - -在你的笔记本电脑上下载并安装[Docker-Desktop](https://www.docker.com/products/docker-desktop)。其中,最新版本包含了Kubernetes,所以不需要额外安装。 -只需按照[这里](https://docs.docker.com/docker-for-mac/#kubernetes)的步骤,就可以在docker-desktop中启动和运行Kubernetes。 - -一旦Kubernetes在docker桌面中启动,你应该看到类似以下的画面: - -![Kubernetes in Docker Desktop](./../assets/docker-desktop.png) - -这意味着: -1. Kubernetes正在运行。 -2. 命令行工具`kubctl`安装在`/usr/local/bin`目录下。 -3. Kubernetes的被设置到`docker-desktop`中。 - -### 部署和访问仪表板 - -设置好本地Kubernetes后,你需要使用以下步骤部署仪表盘: -1. 按照[Kubernetes dashboard doc](https://github.com/kubernetes/dashboard)中的说明来部署仪表盘。 -2. 从终端启动Kubernetes代理,让我们能存取本地主机上的仪表板: - ```shell script - kubectl proxy & - ``` -3. 通过以下网址访问仪表板: [链接](http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login) - -### 访问本地Kubernetes集群 - -上一步部署的仪表板需要一个令牌或配置来登录。这里我们使用令牌来登录。该令牌是自动生成的,可以从系统中检索到。 - -1. 检索仪表板令牌的名称: - ```shell script - kubectl -n kube-system get secret | grep kubernetes-dashboard-token - ``` -2. 检索令牌的内容,注意令牌名称以随机的5个字符代码结尾,需要用步骤1的结果替换。例如: - ```shell script - kubectl -n kube-system describe secret kubernetes-dashboard-token-tf6n8 - ``` -3. 複製`Data`中标签为 `token`的值。 -4. 在用户介面仪表板中选择 **Token**:
- ![Token Access in dashboard](./../assets/dashboard_token_select.png) -5. 在输入框中粘贴`token`的值,然后登录:
- ![Token Access in dashboard](./../assets/dashboard_secret.png) - -## 使用Minikube设置本地的Kubernetes集群 - -Minikube 可以被添加到现有的 Docker Desktop 中。Minikube 既可以使用预装的虚拟机管理程序(hypervisor),也可以自己选择。预设是由[HyperKit](https://github.com/moby/hyperkit)所提供的虚拟化,它已被嵌入到 Docker Desktop 中。 - -如果你不想使用 HyperKit 的虚拟机管理程序,请确保你遵循通用的minikube安装说明。如果需要的话,不要忘记为所选择的虚拟机管理程序安装正确的驱动程序。 -基本说明在[minikube install](https://kubernetes.io/docs/tasks/tools/install-minikube/)中提供。 - -如果要检查 Docker Desktop 是否安装了 HyperKit。在终端上运行: `hyperkit`来确认。除了 `hyperkit: command not found` 以外的任何响应都证实了 HyperKit 已经安装并且在路径上。如果没有找到,你可以选择一个不同的虚拟机管理程序或修复Docker Desktop。 - -### 安装 Minikube -1. 你可以使用 brew 或是以下的步骤来安装 minikube: - ```shell script - curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 - chmod +x minikube - sudo mv minikube /usr/local/bin - ``` -2. 你可以使用 brew 或是以下的步骤来安装 HyperKit 的驱动程序(必要): - ```shell script - curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-hyperkit - sudo install -o root -g wheel -m 4755 docker-machine-driver-hyperkit /usr/local/bin/ - ``` -3. 更新 minikube 配置,使其默认虚拟机管理程序为HyperKit:`minikube config set vm-driver hyperkit`。 -4. 修改 docker desktop 以使用 Kubernetes 的 minikube:
- ![Kubernetes in Docker Desktop: minikube setting](./../assets/docker-dektop-minikube.png) - -### 部署和访问集群 -安装完成后,你可以开始启动一个新的集群。 -1. 启动 minikube 集群: `minikube start --kubernetes-version v1.24.7` -2. 启动 minikube 仪表板: `minikube dashboard &` - -### 开发环境对构建的影响 -在创建映像之前,确保你的 minikube 运行在正确的环境中。 -如果没有设定 minikube 环境,就会在部署调度器的时候找不到docker映像。 -1. 确保 minikube 已启动。 -2. 在你要运行构建的终端中,执行: `eval $(minikube docker-env)` -3. 在 yunikorn-k8shim 的根目录创建映像: `make image` -4. 按照正常指令部署调度器。 - -## 使用 Kind 的设置本地的 Kubernetes 集群 - -Kind(Kubernetes in Docker)是一个轻量级的工具,主要用来运行轻量级Kubernetes环境。 用kind测试不同的Kubernetes版本是非常容易的,只需选择你想要的映像。 - -### 安装 - -如果你已经安装过go,可以直接运行`go install sigs.k8s.io/kind@latest`。 - -可在[Kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)的文件上找到其他方法。 - -Kubernetes 1.25 或更高版本需要 Kind 版本 0.15。Kind 的更高版本添加了 Kubernetes 1.26、1.27 和 1.28。检查种类发行说明以了解支持的特定 Kubernetes 版本 - -### 使用 Kind - -若要要测试新版本的Kubernetes,你可以从kind的repo中拉出一个相应的映像。 - -创建版本为 v1.24.7 的 Kubernetes 集群: `kind create cluster --name test --image kindest/node:v1.24.7` - -删除 kind 集群: `kind delete cluster --name test` - -### 载入你的映像 - -为了使用本地镜像,你必须将你的映像加载到kind的注册表(registry)中。 如果你运行`make image`,你可以使用下面的命令来加载你的kind映像。 以下假设为AMD64架构。 - -下面是调度器、网页UI和存取控制器的例子: - -调度器: -`kind load docker-image apache/yunikorn:scheduler-amd64-latest` - -网页UI: -`kind load docker-image apache/yunikorn:web-amd64-latest` - -存取控制器: -`kind load docker-image apache/yunikorn:admission-amd64-latest` - -## 在本地调试代码 - -注意,这个指令要求你在 GoLand IDE 进行开发。 - -在GoLand中,进入yunikorn-k8shim项目。然后点击 "Run" -> "Debug..." -> "Edit Configuration..." 获取弹出的配置窗口。 -注意,如果第一次没有 "Go Build "选项,你需要点击 "+"来创建一个新的配置文件。 - -![Debug Configuration](./../assets/goland_debug.jpg) - -强调的字段是你需要添加的配置。包括以下: - -- Run Kind: package -- Package path: 指向 `pkg/shim` 的路径 -- Working directory: 指向`conf`目录的路径,这是程序加载配置文件的地方。 -- Program arguments: 指定运行程序的参数,如 `-kubeConfig=/path/to/.kube/config -interval=1s -clusterId=mycluster -clusterVersion=0.1 -name=yunikorn -policyGroup=queues -logEncoding=console -logLevel=-1`. -注意,你需要把`/path/to/.kube/config`替换为kubeconfig文件的本地路径。如果你想改变或添加更多的选项,你可以运行`_output/bin/k8s-yunikorn-scheduler -h`来了解。 - -修改完成后,点击 "Apply",然后点击 "Debug"。你将需要设置适当的断点,以便调试程序。 - -## 存取远端的 Kubernetes 集群 - -这个设置的前提是你已经安装了一个远程Kubernetes集群。 -关于如何访问多个集群并将其整合,请参考Kubernetes的[访问多个集群](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)文档。 - -或者按照这些简化的步骤: -1. 从远程集群获取Kubernetes的`config`文件,将其复制到本地机器上,并给它一个唯一的名字,即`config-remote`。 -2. 更新 `KUBECONFIG` 环境变量(如果已设置)。 - ```shell script - export KUBECONFIG_SAVED=$KUBECONFIG - ``` -3. 将新文件添加到环境变量中。 - ```shell script - export KUBECONFIG=$KUBECONFIG:config-remote - ``` -4. 运行`kubectl config view`命令,检查是否可以访问这两个配置。 -5. 透过以下命令切换配置 `kubectl config use-context my-remote-cluster` -6. 确认是否切换到了远程集群的配置: - ```text - kubectl config get-contexts - CURRENT NAME CLUSTER AUTHINFO NAMESPACE - docker-for-desktop docker-for-desktop-cluster docker-for-desktop - * my-remote-cluster kubernetes kubernetes-admin - ``` - -更多的文件可以在[这里](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)找到。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/openshift_development.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/openshift_development.md deleted file mode 100644 index dad1275a1ea..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/openshift_development.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -id: openshift_development -title: Development in CodeReady Containers ---- - - - -YuniKorn 针对 OpenShift 进行了测试,开发人员可以设置本地环境来针对 OpenShift 测试补丁。 -我们推荐本地环境使用 CodeReady 容器。 - -## 设置正在运行的 CRC 集群 - -1. 下载 CodeReady 容器二进制文件 - - 从下拉列表中选择您的操作系统,然后单击“下载”(在 Mac 上,您将下载 crc-macos-amd64.tar.xz;在 Linux 上,crc-linux-amd64.tar.xz)。 - 系统会要求您使用 Red Hat 登录名进行连接。 如果您没有,只需单击“立即创建”。 您 *不* 需要 Red Hat 订阅。 - - 登录后,下载 CodeReady Containers 二进制文件和 pull secret。 - -1. 解压缩 tar 文件。 - - ```bash - tar -xvzf crc-macos-amd64.tar.xz - ``` - -1. 将 crc 二进制文件移到您的路径下。 像 - - ```bash - sudo cp `pwd`/crc-macos-$CRCVERSION-amd64/crc /usr/local/bin - ``` - -1. 根据您的硬件能力配置 CRC 。 - - ```bash - crc config set memory 16000 - crc config set cpus 12 - crc setup - ``` -1. 启动 CRC 并打开控制台。 - - ```bash - crc start --pull-secret-file pull-secret.txt - crc console - ``` - -## 测试补丁 - -以下步骤假设您的笔记本电脑中有一个正在运行的 CRC 集群。 -:::note -这些步骤未针对远程 CRC 集群进行测试。 -::: - -1. 通过 `oc` 命令访问您的环境。 - - 在 shell 中输入 `crc oc-env` 命令。 - ```bash - $ crc oc-env - export PATH="/Users//.crc/bin/oc:$PATH" - # Run this command to configure your shell: - # eval $(crc oc-env) - ``` - 所以你需要输入这个来访问 `oc` 命令: - ``` - eval $(crc oc-env) - ``` - -1. 登录到 “oc” 。 CRC 启动后,它会显示类似的消息: - - ``` - To access the cluster, first set up your environment by following 'crc oc-env' instructions. - Then you can access it by running 'oc login -u developer -p developer https://api.crc.testing:6443'. - To login as an admin, run 'oc login -u kubeadmin -p duduw-yPT9Z-hsUpq-f3pre https://api.crc.testing:6443'. - To access the cluster, first set up your environment by following 'crc oc-env' instructions. - ``` - - 使用 `oc login -u kubeadmin ...` 命令。 - -1. 通过输入以下命令获取本地 OpenShift 集群的内部私有 Docker 存储库的 URL。 - - ```bash - $ oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}' - default-route-openshift-image-registry.apps-crc.testing - ``` - - 默认情况下,它应该是 “default-route-openshift-image-registry.apps-crc.testing” 。 如果显示的 URL 不同,请更改上述步骤。 - -1. 准备 Docker 镜像。 - - 您可以在底部的 *使用自定义镜像* 部分阅读更多相关信息。 - -1. 准备 helm chart. - - 如果您想使用自定义 Docker 镜像,请替换 helm chart 的 “values.yaml” 配置文件中的镜像。 - - :::note - 如果您直接将 Docker 镜像手动推送到 `default-route-openshift-image-registry.apps-crc.testing` docker registry ,您需要有有效的证书才能访问它。 - 在 OpenShift 上有更容易使用的服务:`image-registry.openshift-image-registry.svc`。 - ::: - - 例如,如果你想覆盖所有 Docker 镜像,你应该使用以下配置: - ```yaml - image: - repository: image-registry.openshift-image-registry.svc:5000/yunikorn/yunikorn - tag: scheduler-latest - pullPolicy: Always - - admission_controller_image: - repository: image-registry.openshift-image-registry.svc:5000/yunikorn/yunikorn - tag: admission-latest - pullPolicy: Always - - web_image: - repository: image-registry.openshift-image-registry.svc:5000/yunikorn/yunikorn-web - tag: latest - pullPolicy: Always - ``` - - 您可以在 yunikorn-release 存储库的 helm chart 目录中找到它。 - -1. 安装 helm charts. - - ```bash - helm install yunikorn . -n yunikorn - ``` - -## 使用自定义镜像 - -### Podman - -1. 使用以下命令登录 Podman。 - - ```bash - podman login --tls-verify=false -u kubeadmin -p $(oc whoami -t) default-route-openshift-image-registry.apps-crc.testing - ``` - -1. 在存储库中构建镜像,例如 在 shim 中使用通用的 “make image” 命令。 - -1. 验证镜像是否存在于存储库中。 - - ```bash - podman images - REPOSITORY TAG IMAGE ID CREATED SIZE - localhost/apache/yunikorn admission-latest 19eb41241d64 About a minute ago 53.5 MB - localhost/apache/yunikorn scheduler-latest e60e09b424d9 About a minute ago 543 MB - ``` - -## 直接推送 OS 镜像注册 - -1. 创建您要替换的镜像。 - - 您可以在本地构建新镜像或使用官方镜像(也可以混合使用)。 - * 对于 -shim 和 -web 镜像检查存储库(可选择进行更改)并输入以下命令: - ```bash - make clean image REGISTRY=default-route-openshift-image-registry.apps-crc.testing//: - ``` - :::note - 在 OpenShift 中,一个计划相当于一个 Kubernetes 命名空间。 推荐使用 `yunikorn` 项目/命名空间。 - ::: - - * 可以使用官方镜像,通过 “docker tag” 命令重新标记。 - ```bash - docker tag apache/yunikorn:scheduler-latest default-route-openshift-image-registry.apps-crc.testing/yunikorn/yunikorn:scheduler-latest - ``` - -1. 登录到 Docker 存储库。 - ```bash - docker login -u kubeadmin -p $(oc whoami -t) default-route-openshift-image-registry.apps-crc.testing - ``` - -1. 将 Docker 镜像推送到内部 Docker 存储库 - ``` - docker push default-route-openshift-image-registry.apps-crc.testing/yunikorn/yunikorn:scheduler-latest - ``` \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/translation.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/translation.md deleted file mode 100644 index 2e74494ed86..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/developer_guide/translation.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: translation -title: 翻译 ---- - - - -Yunikorn网站采用Docusaurus管理文档。 -[Docusaurus国际化系统(i18n)](https://docusaurus.io/docs/i18n/tutorial)允许开发人员翻译文档。 -为网站添加新的语言翻译时,开发者应进行如下操作。 - -## 修改docusaurus.config.js以支持新语言 -假设通过**新语言关键字**进行翻译。 -预期的结果会像这个图(右上方的<新语言关键字>為test)。 -![翻译结果](./../assets/translationDemo.png) - -当前的Yunikorn网站包括**en**和**zh-cn**文档。 -如果开发者想添加一个新的带有**新语言关键字**的翻译,如fr, jp。 -则开发者需要修改`docusaurus.config.js`中的`i18n`栏位。 -``` -i18n: { - defaultLocale: 'en', - locales: ['en', 'zh-cn', '<新语言关键字>'], - localeConfigs: { - en: { - label: 'English', - }, - "zh-cn": { - label: '中文', - }, - "<新语言关键字>": { - label: 'test', - } - }, - }, -``` -## 更新local-build.sh中的帮助信息 -将**新语言关键字**添加到`print_usage`函数的语言环境列表中。 -``` -Usage: $(basename "$0") run [locale] | build | clean | help - run build the website, and launch the server in a docker image. - a locale can be specified, currently supported: "en", "zh-cn", "<新语言关键字>" -``` - -## 将最新文件复制到i18n资料夹 -``` -mkdir -p i18n/<新语言关键字>/docusaurus-plugin-content-docs/current -cp -r docs/** i18n/<新语言关键字>/docusaurus-plugin-content-docs/current -mkdir -p i18n/<新语言关键字>/docusaurus-plugin-content-pages -cp -r src/pages/** i18n/<新语言关键字>/docusaurus-plugin-content-pages -mkdir -p i18n/<新语言关键字>/docusaurus-theme-classic -``` - -## 在sidebar.json和footer.json中添加翻译后的信息 -在docusaurus-theme-classic资料夹中创建sidebar.json和footer.json档案。 -例如,添加的footer.json内容如下。 -``` -{ - "link.item.label.Get Involved": { - "message": "参与" - }, - "link.title.Code Repositories": { - "message": "代码库" - }, - "link.item.label.People": { - "message": "人们" - }, - "link.title.Blog": { - "message": "博客" - }, - "link.title.Community": { - "message": "社区" - } -} -``` - - - -## 链接img、assest与styles.module.css -在`i18n/new language keyword/docusaurus-plugin-content-pages`中创建链接文件。 - -``` -# 清理重复文件 -rm -rf img -rm styles.module.css -# 链接 -ln -s ../../../static/img -ln -s ../../../src/pages/styles.module.css -``` - -在`i18n/new language keyword/docusaurus-plugin-content-docs/current`中创建链接文件。 -``` -# 清理重复文件 -rm -rf assests -# 链接 -ln -s ../../../../docs/assets -``` - -## 采用相对路径 -`src/pages/index.js`中有部分图片url采用绝对路径,采用绝对路径会导致png丢失。 -开发人员需要确保`/i18n/new language keyword/docusaurus-plugin-content-pages/index.js`中的图链接有效。 -例如,在`index.js`中有一个`resource-scheduling.png`图像,图像链接是`/img/resource-scheduling.png`。 -``` -/img/resource-scheduling.png -> ./img/resource-scheduling.png -``` -## 测试 -``` -./local-build.sh run <新语言关键字> -``` -![建设网站](./../assets/translationBuilding.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/core_features.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/core_features.md deleted file mode 100644 index d6d3c497992..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/core_features.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: core_features -title: 特征 -keywords: - - 特征 ---- - - - -YuniKorn的主要特点包括: - -## 应用感知调度 - -YuniKorn的关键特性之一就是支持应用感知。在默认的K8s调度程序中,它只能根据Pod进行调度,而不能基于用户、作业或者队列进行更细粒度的调度。 -与之不同的是,YuniKorn可以识别用户、作业或者队列,并在做出调度决策时,考虑更多与它们相关的因素,如资源、排序等。 -这使我们能够对资源配额、资源公平性和优先级进行细粒度控制,这是多租户计算系统最重要的需求。 - -## 层次资源队列 - -层次队列提供了一种有效的机制来管理集群资源。 -队列的层次结构可以在逻辑上映射到组织结构。这为不同租户提供了对资源的细粒度控制。 -YuniKorn UI 提供了一个集中的视图来监视资源队列的使用情况,它可以帮助您了解不同租户是如何使用资源的。 -此外,用户可以利用设置最小/最大队列容量来为每个租户设定其弹性资源配额。 - -## 作业排序和排队 - -YuniKorn将每个资源队列中的队列进行排队,排序策略决定哪个应用程序可以首先获得资源。 -这个策略可以是多种多样的,例如简单的 `FIFO`、`Fair`、`StateAware` 或基于 `Priority` 的策略。 -队列可以维持应用的顺序,调度器根据不同的策略为作业分配相应的资源。这种行为更容易被理解和控制。 - -此外,当配置队列最大容量时,作业和任务可以在资源队列中正确排队。 -如果剩余的容量不够,它们可以排队等待,直到释放一些资源。这就简化了客户端操作。 -而在默认调度程序中,资源由命名空间资源配额限制:如果命名空间没有足够的配额,Pod就不能被创建。这是由配额许可控制器强制执行的。 -客户端需要更复杂的逻辑来处理此类场景,例如按条件重试。 - -## 资源公平性 - -在多租户环境中,许多用户共享集群资源。 -为了避免租户争夺资源或者可能的资源不足,需要做到更细粒度的公平性需求,以此来实现跨用户以及跨团队/组织的公平性。 -考虑到权重或优先级,一些更重要的应用可以获得超过其配额的更多的需求资源。 -这往往与资源预算有关,更细粒度的公平模式可以进一步提高资源控制。 - -## 资源预留 - -YuniKorn会自动为未完成的请求进行资源预留。 -如果Pod无法分配,YuniKorn将尝试把它预留在一个满足条件的节点上,并在这个节点上暂时分配该 pod(在尝试其他节点之前)。 -这种机制可以避免这个 Pod 需要的资源被后来提交的更小的、更不挑剔的 Pod 所挤占。 -此功能在批处理工作负载场景中非常重要,因为当对集群提交大量异构 Pod 时,很有可能一些 Pod 会处于“饥饿”状态,即使它们提交得更早。 - -## 吞吐量 - -吞吐量是衡量调度器性能的关键标准。这对于一个大规模的分布式系统来说是至关重要的。 -如果吞吐量不好,应用程序可能会浪费时间等待调度,并进一步影响服务的 SLA(服务级别协议)。 -集群越大,对吞吐量的要求也越高。[基于Kube标记的运行评估](performance/evaluate_perf_function_with_kubemark.md) 章节显示了一些性能数据。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/get_started.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/get_started.md deleted file mode 100644 index fcf009f0f5e..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/get_started.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: user_guide -title: 开始 -slug: / ---- - - - -在阅读本指南之前,我们假设您有一个Kubernetes集群或本地 Kubernetes 开发环境,例如 MiniKube。 -还假定 `kubectl` 在您的环境路径内,并且配置正确。 -遵循此 [指南](developer_guide/env_setup.md) 来讲述如何使用 docker-desktop 设置本地Kubernetes集群。 - -## 安装 - -最简单的方法是使用我们的 Helm Chart 在现有的Kubernetes集群上部署YuniKorn。 -我们建议使用 Helm 3 或更高版本。 - -```shell script -helm repo add yunikorn https://apache.github.io/yunikorn-release -helm repo update -kubectl create namespace yunikorn -helm install yunikorn yunikorn/yunikorn --namespace yunikorn -``` - -默认情况下,Helm Chart 将在集群中安装调度器、web服务器和 admission-controller。 -`admission-controller` 一旦安装,它将把所有集群流量路由到YuniKorn。 -这意味着资源调度会委托给YuniKorn。在Helm安装过程中,可以通过将 `embedAdmissionController` 标志设置为 `false` 来禁用它。 -通过将Helm的 `enableSchedulerPlugin` 标志设置为 `true`,YuniKorn调度器也可以以Kubernetes的调度器插件的方式进行部署。 -这种方式将会部署一个包含与默认调度器一起编译的YuniKorn备用Docker镜像。 -这种新模式借助默认的Kubernetes调度器提供了更好的兼容性,并且适合与将所有调度委托给YuniKorn的 admission-controller 协同使用。 -因为这个模式还是很新的,所以默认没有开启。 - -如果您不确定应该使用哪种部署模式,请参阅我们 [并列比较](user_guide/deployment_modes) 章节的内容。 - -如果你不想使用 Helm Chart,您可以找到我们的细节教程 [点击这里](developer_guide/deployment.md) 。 - -## 卸载 - -运行如下的命令卸载 YuniKorn: - -```shell script -helm uninstall yunikorn --namespace yunikorn -``` - -## 访问 Web UI - -当部署调度程序时,Web UI 也会部署在容器中。 -我们可以通过以下方式在标准端口上打开 Web 界面的端口转发: - -```shell script -kubectl port-forward svc/yunikorn-service 9889:9889 -n yunikorn -``` - -`9889` 是 Web UI 的默认端口。 -完成此操作后,web UI将在以下地址可用: http://localhost:9889 。 - -![UI 截图](./../assets/yk-ui-screenshots.gif) - -YuniKorn UI 提供了集群资源容量、利用率和所有应用信息的集中视图。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/version.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/version.md deleted file mode 100644 index 6ce8e97d76c..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/get_started/version.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -id: version -title: 版本详情 ---- - - - -# 应该使用哪个版本? - - -建议始终运行最新版本的 YuniKorn。新版本定期由 YuniKorn 本身和/或 shim 的新功能驱动。目前新功能和修复仅合并到用来做释出的开发分支。 - -此时该项目仅创建次要版本,没有补丁版本。 - -如果 shim 版本(即 Kubernetes)受多个 YuniKorn 版本支持,我们建议始终使用最新的 YuniKorn 版本。 -早期版本中较旧的构建依赖项可能会阻止您使用 shim 的某些新功能。 - -# YuniKorn 支持的 Kubernetes 版本 - -| K8s 版本 | 发行版本 | 支持结束 | -|--------------|:------:|:------:| -| 1.12.x (或更早) | - | - | -| 1.13.x | 0.8.0 | 0.10.0 | -| 1.14.x | 0.8.0 | 0.10.0 | -| 1.15.x | 0.8.0 | 0.10.0 | -| 1.16.x | 0.10.0 | 0.11.0 | -| 1.17.x | 0.10.0 | 0.11.0 | -| 1.18.x | 0.10.0 | 0.11.0 | -| 1.19.x | 0.11.0 | 1.0.0 | -| 1.20.x | 0.12.1 | 1.2.0 | -| 1.21.x | 0.12.1 | 1.3.0 | -| 1.22.x | 0.12.2 | 1.3.0 | -| 1.23.x | 0.12.2 | 1.3.0 | -| 1.24.x | 1.0.0 | - | -| 1.25.x | 1.2.0 | - | -| 1.26.x | 1.2.0 | - | -| 1.27.x | 1.4.0 | - | -| 1.28.x | 1.4.0 | - | -| 1.29.x | 1.5.0 | - | - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/evaluate_perf_function_with_kubemark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/evaluate_perf_function_with_kubemark.md deleted file mode 100644 index 44f4c67ebda..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/evaluate_perf_function_with_kubemark.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: evaluate_perf_function_with_kubemark -title: 使用 Kubemark 评估 YuniKorn 的性能 -keywords: - - 性能 - - 吞吐量 ---- - - - -YuniKorn 社区关注调度程序的性能,并继续在发布时对其进行优化。 社区已经开发了一些工具来反复测试和调整性能。 - -## 环境设置 - -我们利用[Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster)评估调度器的性能。 Kubemark是一个模拟大规模集群的测试工具。 它创建空节点,运行空kubelet以假装原始kubelet行为。 这些空节点上的调度pod不会真正执行。它能够创建一个满足我们实验要求的大集群,揭示yunikorn调度器的性能。 请参阅有关如何设置环境的[详细步骤](performance/performance_tutorial.md)。 - -## 调度程序吞吐量 - -我们在模拟的大规模环境中设计了一些简单的基准测试场景,以评估调度器的性能。 我们的工具测量[吞吐量](https://en.wikipedia.org/wiki/Throughput)并使用这些关键指标来评估性能。 简而言之,调度程序吞吐量是处理pod从在集群上发现它们到将它们分配给节点的速率。 - -在本实验中,我们使用 [Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster) 设置了一个模拟的2000/4000节点集群。然后我们启动10个[部署](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/),每个部署分别设置5000个副本。 这模拟了大规模工作负载同时提交到K8s集群。 我们的工具会定期监控和检查pod状态,随着时间的推移,根据 `podSpec.StartTime` 计算启动的pod数量。 作为对比,我们将相同的实验应用到相同环境中的默认调度程序。 我们看到了YuniKorn相对于默认调度程序的性能优势,如下图所示: - -![Scheduler Throughput](./../assets/yunirkonVSdefault.png) -

图 1. Yunikorn 和默认调度器吞吐量

- -图表记录了集群上所有 Pod 运行所花费的时间: - -| 节点数 | yunikorn | k8s 默认调度器 | 差异 | -|------------------ |:--------------: |:---------------------: |:-----: | -| 2000(节点) | 204(pods/秒) | 49(pods/秒) | 416% | -| 4000(节点) | 115(pods/秒) | 48(pods/秒) | 240% | - -为了使结果标准化,我们已经运行了几轮测试。 如上所示,与默认调度程序相比,YuniKorn实现了`2 倍`~`4 倍`的性能提升。 - -:::note - -与其他性能测试一样,结果因底层硬件而异,例如服务器CPU/内存、网络带宽、I/O速度等。为了获得适用于您的环境的准确结果,我们鼓励您运行这些测试在靠近生产环境的集群上。 - -::: - -## 性能分析 - -我们从实验中得到的结果是有希望的。 我们通过观察更多的YuniKorn内部指标进一步深入分析性能,我们能够找到影响性能的几个关键区域。 - -### K8s 限制 - -我们发现整体性能实际上受到了K8s主服务的限制,例如api-server、controller-manager和etcd,在我们所有的实验中都没有达到YuniKorn的限制。 如果您查看内部调度指标,您可以看到: - -![Allocation latency](./../assets/allocation_4k.png) -

图 2. 4k 节点中的 Yunikorn 指标

- -图2是Prometheus的截图,它记录了YuniKorn中的[内部指标](performance/metrics.md) `containerAllocation`。 它们是调度程序分配的 pod 数量,但不一定绑定到节点。 完成调度50k pod大约需要122秒,即410 pod/秒。 实际吞吐量下降到115个 Pod/秒,额外的时间用于绑定不同节点上的Pod。 如果K8s方面能赶上来,我们会看到更好的结果。 实际上,当我们在大规模集群上调整性能时,我们要做的第一件事就是调整API-server、控制器管理器中的一些参数,以提高吞吐量。 在[性能教程文档](performance/performance_tutorial.md)中查看更多信息。 - -### 节点排序 - -当集群大小增加时,我们看到YuniKorn的性能明显下降。 这是因为在YuniKorn中,我们对集群节点进行了完整排序,以便为给定的pod找到 **“best-fit”** 节点。 这种策略使Pod分布更加优化,基于所使用的 [节点排序策略](./../user_guide/sorting_policies#node-sorting)。 但是,对节点进行排序很昂贵,在调度周期中这样做会产生很多开销。 为了克服这个问题,我们在 [YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807) 中改进了我们的节点排序机制,其背后的想法是使用 [B-Tree ](https://en.wikipedia.org/wiki/B-tree)来存储所有节点并在必要时应用增量更新。 这显着改善了延迟,根据我们的基准测试,这在500、1000、2000 和 5000个节点的集群上分别提高了 35 倍、42 倍、51 倍、74 倍。 - -### 每个节点的前提条件检查 - -在每个调度周期中,另一个耗时的部分是节点的“前提条件检查”。 在这个阶段,YuniKorn评估所有K8s标准断言(Predicates),例如节点选择器、pod亲和性/反亲和性等,以确定pod是否适合节点。 这些评估成本很高。 - -我们做了两个实验来比较启用和禁用断言评估的情况。 请参阅以下结果: - -![Allocation latency](./../assets/predicateComaparation.png) -

图 3. Yunikorn 中的断言效果比较

- -当断言评估被禁用时,吞吐量会提高很多。 我们进一步研究了整个调度周期的延迟分布和断言评估延迟。 并发现: - -![YK predicate latency](./../assets/predicate_4k.png) -

图 4. 断言延迟

- -![YK scheduling with predicate](./../assets/scheduling_with_predicate_4k_.png) -

图 5. 启用断言的调度时间

- -![YK scheduling with no predicate](./../assets/scheduling_no_predicate_4k.png) -

图 6. 不启用断言的调度时间

- -总体而言,YuniKorn 调度周期运行得非常快,每个周期的延迟下降在 **0.001s - 0.01s** 范围内。 并且大部分时间用于断言评估,10倍于调度周期中的其他部分。 - -| | 调度延迟分布(秒) | 断言-评估延迟分布(秒) | -|----------------------- |:---------------------: |:---------------------: | -| 启用断言 | 0.01 - 0.1 | 0.01-0.1 | -| 不启用断言 | 0.001 - 0.01 | 无 | - -## 为什么 YuniKorn 更快? - -默认调度器被创建为面向服务的调度器; 与YuniKorn相比,它在吞吐量方面的敏感性较低。 YuniKorn社区非常努力地保持出色的性能并不断改进。 YuniKorn可以比默认调度器运行得更快的原因是: - -* 短调度周期 - -YuniKorn 保持调度周期短而高效。 YuniKorn 使用所有异步通信协议来确保所有关键路径都是非阻塞调用。 大多数地方只是在进行内存计算,这可能非常高效。 默认调度器利用 [调度框架](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/),它为扩展调度器提供了很大的灵活性,但是,权衡是性能。 调度周期变成了一条很长的链,因为它需要访问所有这些插件。 - -* 异步事件处理 - -YuniKorn利用异步事件处理框架来处理内部状态。 这使得核心调度周期可以快速运行而不会被任何昂贵的调用阻塞。 例如,默认调度程序需要将状态更新、事件写入pod对象,这是在调度周期内完成的。 这涉及将数据持久化到etcd,这可能很慢。 YuniKorn将所有此类事件缓存在一个队列中,并以异步方式写回pod。 - -* 更快的节点排序 - -[YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807)之后,YuniKorn进行了高效的增量节点排序。 这是建立在所谓的基于“资源权重”的节点评分机制之上的,它也可以通过插件进行扩展。 所有这些一起减少了计算节点分数时的开销。 相比之下,默认调度器提供了一些计算节点分数的扩展点,例如`PreScore`、`Score`和`NormalizeScore`。 这些计算量很大,并且在每个调度周期中都会调用它们。 请参阅[代码行](https://github.com/kubernetes/kubernetes/blob/481459d12dc82ab88e413886e2130c2a5e4a8ec4/pkg/scheduler/framework/runtime/framework.go#L857)中的详细信息。 - -## 概括 - -在测试过程中,我们发现YuniKorn的性能非常好,尤其是与默认调度程序相比。 我们已经确定了YuniKorn中可以继续提高性能的主要因素,并解释了为什么YuniKorn的性能优于默认调度程序。 我们还意识到将Kubernetes扩展到数千个节点时的局限性,可以通过使用其他技术(例如联合)来缓解这些局限性。 因此,YuniKorn是一个高效、高吞吐量的调度程序,非常适合在Kubernetes上运行批处理/混合工作负载。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/metrics.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/metrics.md deleted file mode 100644 index 7d6fa73e5b8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/metrics.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: metrics -title: 调度程序指标 -keywords: - - 指标 ---- - - - -YuniKorn利用[Prometheus](https://prometheus.io/) 记录指标。 度量系统不断跟踪调度程序的关键执行路径,以揭示潜在的性能瓶颈。 目前,这些指标分为三类: - -- 调度器:调度器的通用指标,例如分配延迟、应用程序数量等。 -- 队列:每个队列都有自己的指标子系统,跟踪队列状态。 -- 事件:记录YuniKorn中事件的各种变化。 - -所有指标都在`yunikorn`命名空间中声明。 -### 调度程序指标 - -| 指标名称 | 指标类型 | 描述 | -| --------------------- | ------------ | ------------ | -| containerAllocation | Counter | 尝试分配容器的总次数。 尝试状态包括`allocated`, `rejected`, `error`, `released`。 该指标只会增加。 | -| applicationSubmission | Counter | 提交申请的总数。 尝试的状态包括 `accepted`和`rejected`。 该指标只会增加。 | -| applicationStatus | Gauge | 申请状态总数。 应用程序的状态包括`running`和`completed`。 | -| totalNodeActive | Gauge | 活动节点总数。 | -| totalNodeFailed | Gauge | 失败节点的总数。 | -| nodeResourceUsage | Gauge | 节点的总资源使用情况,按资源名称。 | -| schedulingLatency | Histogram | 主调度例程的延迟,以秒为单位。 | -| nodeSortingLatency | Histogram | 所有节点排序的延迟,以秒为单位。 | -| appSortingLatency | Histogram | 所有应用程序排序的延迟,以秒为单位。 | -| queueSortingLatency | Histogram | 所有队列排序的延迟,以秒为单位。 | -| tryNodeLatency | Histogram | 节点条件检查容器分配的延迟,例如放置约束,以秒为单位。 | - -### 队列指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------- | ------------- | ----------- | -| appMetrics | Counter | 应用程序指标,记录申请总数。 应用程序的状态包括`accepted`、`rejected`和`Completed`。 | -| usedResourceMetrics | Gauge | 排队使用的资源。 | -| pendingResourceMetrics | Gauge | 排队等待的资源。 | -| availableResourceMetrics | Gauge | 与队列等相关的已用资源指标。 | - -### 事件指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------ | ------------ | ----------- | -| totalEventsCreated | Gauge | 创建的事件总数。 | -| totalEventsChanneled | Gauge | 引导的事件总数。 | -| totalEventsNotChanneled | Gauge | 引导的事件总数。 | -| totalEventsProcessed | Gauge | 处理的事件总数。 | -| totalEventsStored | Gauge | 存储的事件总数。 | -| totalEventsNotStored | Gauge | 未存储的事件总数。 | -| totalEventsCollected | Gauge | 收集的事件总数。 | - -## 访问指标 - -YuniKorn指标通过Prometheus客户端库收集,并通过调度程序RESTful服务公开。 -启动后,可以通过端点http://localhost:9080/ws/v1/metrics访问它们。 - -## Prometheus 的聚合指标 - -设置 Prometheus 服务器以定期获取 YuniKorn 指标很简单。 按着这些次序: - -- 设置Prometheus(从[Prometheus 文档](https://prometheus.io/docs/prometheus/latest/installation/)了解更多信息) - -- 配置Prometheus规则:示例配置 - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] -``` - -- 启动 Prometheus - -```shell script -docker pull prom/prometheus:latest -docker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus -``` - -如果您在Mac OS上的本地docker容器中运行Prometheus,请使用`docker.for.mac.host.internal`而不是`localhost`。 启动后,打开Prometheus网页界面:http://localhost:9090/graph。 您将看到来自YuniKorn调度程序的所有可用指标。 - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/performance_tutorial.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/performance_tutorial.md deleted file mode 100644 index 8180fa0716d..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/performance_tutorial.md +++ /dev/null @@ -1,451 +0,0 @@ ---- -id: performance_tutorial -title: 基准测试教程 -keywords: - - 性能 - - 教程 ---- - - - -## 概述 - -YuniKorn社区不断优化调度器的性能,确保YuniKorn满足大规模批处理工作负载的性能要求。 因此,社区为性能基准测试构建了一些有用的工具,可以跨版本重用。 本文档介绍了所有这些工具和运行它们的步骤。 - -## 硬件 - -请注意,性能结果因底层硬件而异。 文档中发布的所有结果只能作为参考。 我们鼓励每个人在自己的环境中运行类似的测试,以便根据您自己的硬件获得结果。 本文档仅用于演示目的。 - -本次测试中使用的服务器列表是(非常感谢[国立台中教育大学](http://www.ntcu.edu.tw/newweb/index.htm), [Kuan-Chou Lai](http://www.ntcu.edu.tw/kclai/) 为运行测试提供这些服务器): - -| 机型 | CPU | 内存 | 下载/上传(Mbps) | -| --------------------- | --- | ------ | --------------------- | -| HP | 16 | 36G | 525.74/509.86 | -| HP | 16 | 30G | 564.84/461.82 | -| HP | 16 | 30G | 431.06/511.69 | -| HP | 24 | 32G | 577.31/576.21 | -| IBM blade H22 | 16 | 38G | 432.11/4.15 | -| IBM blade H22 | 16 | 36G | 714.84/4.14 | -| IBM blade H22 | 16 | 42G | 458.38/4.13 | -| IBM blade H22 | 16 | 42G | 445.42/4.13 | -| IBM blade H22 | 16 | 32G | 400.59/4.13 | -| IBM blade H22 | 16 | 12G | 499.87/4.13 | -| IBM blade H23 | 8 | 32G | 468.51/4.14 | -| WS660T | 8 | 16G | 87.73/86.30 | -| ASUSPRO D640MB_M640SA | 4 | 8G | 92.43/93.77 | -| PRO E500 G6_WS720T | 16 | 8G | 90/87.18 | -| WS E500 G6_WS720T | 8 | 40G | 92.61/89.78 | -| E500 G5 | 8 | 8G | 91.34/85.84 | -| WS E500 G5_WS690T | 12 | 16G | 92.2/93.76 | -| WS E500 G5_WS690T | 8 | 32G | 91/89.41 | -| WS E900 G4_SW980T | 80 | 512G | 89.24/87.97 | - -每个服务器都需要执行以下步骤,否则由于用户/进程/打开文件的数量有限,大规模测试可能会失败。 - -### 1. 设置/etc/sysctl.conf -``` -kernel.pid_max=400000 -fs.inotify.max_user_instances=50000 -fs.inotify.max_user_watches=52094 -``` -### 2. 设置/etc/security/limits.conf - -``` -* soft nproc 4000000 -* hard nproc 4000000 -root soft nproc 4000000 -root hard nproc 4000000 -* soft nofile 50000 -* hard nofile 50000 -root soft nofile 50000 -root hard nofile 50000 -``` ---- - -## 部署工作流 - -在进入细节之前,这里是我们测试中使用的一般步骤: - -- [步骤 1](#Kubernetes): 正确配置Kubernetes API服务器和控制器管理器,然后添加工作节点。 -- [步骤 2](#Setup-Kubemark): 部署空pod,将模拟工作节点,命名空节点。 在所有空节点都处于就绪状态后,我们需要封锁(cordon)所有本地节点,这些本地节点是集群中的物理存在,而不是模拟节点,以避免我们将测试工作负载 pod 分配给本地节点。 -- [步骤 3](#Deploy-YuniKorn): 在主节点上使用Helm chart部署YuniKorn,并将 Deployment 缩减为 0 副本,并在`prometheus.yml`中 [修改端口](#Setup-Prometheus) 以匹配服务的端口。 -- [步骤 4](#Run-tests): 部署50k Nginx pod进行测试,API服务器将创建它们。 但是由于YuniKorn调度程序Deployment已经被缩减到0个副本,所有的Nginx pod都将停留在等待状态。 -- [步骤 5](../user_guide/troubleshooting.md#restart-the-scheduler): 将YuniKorn部署扩展回1个副本,并封锁主节点以避免YuniKorn 在那里分配Nginx pod。 在这一步中,YuniKorn将开始收集指标。 -- [步骤 6](#Collect-and-Observe-YuniKorn-metrics): 观察Prometheus UI中公开的指标。 ---- - -## 设置 Kubemark - -[Kubemark](https://github.com/kubernetes/kubernetes/tree/master/test/kubemark)是一个性能测试工具,允许用户在模拟集群上运行实验。 主要用例是可扩展性测试。 基本思想是在一个物理节点上运行数十或数百个假kubelet节点,以模拟大规模集群。 在我们的测试中,我们利用 Kubemark 在少于20个物理节点上模拟多达4K节点的集群。 - -### 1. 构建镜像 - -##### 克隆kubernetes仓库,并构建kubemark二进制文件 - -``` -git clone https://github.com/kubernetes/kubernetes.git -``` -``` -cd kubernetes -``` -``` -KUBE_BUILD_PLATFORMS=linux/amd64 make kubemark GOFLAGS=-v GOGCFLAGS="-N -l" -``` - -##### 将kubemark二进制文件复制到镜像文件夹并构建kubemark docker镜像 - -``` -cp _output/bin/kubemark cluster/images/kubemark -``` -``` -IMAGE_TAG=v1.XX.X make build -``` -完成此步骤后,您可以获得可以模拟集群节点的kubemark镜像。 您可以将其上传到Docker-Hub或仅在本地部署。 - -### 2. 安装Kubermark - -##### 创建kubemark命名空间 - -``` -kubectl create ns kubemark -``` - -##### 创建configmap - -``` -kubectl create configmap node-configmap -n kubemark --from-literal=content.type="test-cluster" -``` - -##### 创建secret - -``` -kubectl create secret generic kubeconfig --type=Opaque --namespace=kubemark --from-file=kubelet.kubeconfig={kubeconfig_file_path} --from-file=kubeproxy.kubeconfig={kubeconfig_file_path} -``` -### 3. 标签节点 - -我们需要给所有的原生节点打上标签,否则调度器可能会将空pod分配给其他模拟的空节点。 我们可以利用yaml中的节点选择器将空pod分配给本地节点。 - -``` -kubectl label node {node name} tag=tagName -``` - -### 4. 部署Kubemark - -hollow-node.yaml如下所示,我们可以配置一些参数。 - -``` -apiVersion: v1 -kind: ReplicationController -metadata: - name: hollow-node - namespace: kubemark -spec: - replicas: 2000 # 要模拟的节点数 - selector: - name: hollow-node - template: - metadata: - labels: - name: hollow-node - spec: - nodeSelector: # 利用标签分配给本地节点 - tag: tagName - initContainers: - - name: init-inotify-limit - image: docker.io/busybox:latest - imagePullPolicy: IfNotPresent - command: ['sysctl', '-w', 'fs.inotify.max_user_instances=200'] # 设置为与实际节点中的max_user_instance相同 - securityContext: - privileged: true - volumes: - - name: kubeconfig-volume - secret: - secretName: kubeconfig - - name: logs-volume - hostPath: - path: /var/log - containers: - - name: hollow-kubelet - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 4194 - - containerPort: 10250 - - containerPort: 10255 - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=kubelet - - --name=$(NODE_NAME) - - --kubeconfig=/kubeconfig/kubelet.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: - requests: # 空pod的资源,可以修改。 - cpu: 20m - memory: 50M - securityContext: - privileged: true - - name: hollow-proxy - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=proxy - - --name=$(NODE_NAME) - - --use-real-proxier=false - - --kubeconfig=/kubeconfig/kubeproxy.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: # 空pod的资源,可以修改。 - requests: - cpu: 20m - memory: 50M - tolerations: - - effect: NoExecute - key: node.kubernetes.io/unreachable - operator: Exists - - effect: NoExecute - key: node.kubernetes.io/not-ready - operator: Exists -``` - -完成编辑后,将其应用于集群: - -``` -kubectl apply -f hollow-node.yaml -``` - ---- - -## 部署 YuniKorn - -#### 使用helm安装YuniKorn - -我们可以用 Helm 安装 YuniKorn,请参考这个[文档](https://yunikorn.apache.org/docs/#install)。 我们需要根据默认配置调整一些参数。 我们建议克隆[发布仓库](https://github.com/apache/yunikorn-release)并修改`value.yaml`中的参数。 - -``` -git clone https://github.com/apache/yunikorn-release.git -cd helm-charts/yunikorn -``` - -#### 配置 - -`value.yaml`中的修改是: - -- 增加调度程序 pod 的内存/cpu 资源 -- 禁用 admission controller -- 将应用排序策略设置为 FAIR - -请参阅以下更改: - -``` -resources: - requests: - cpu: 14 - memory: 16Gi - limits: - cpu: 14 - memory: 16Gi -``` -``` -embedAdmissionController: false -``` -``` -configuration: | - partitions: - - - name: default - queues: - - name: root - submitacl: '*' - queues: - - - name: sandbox - properties: - application.sort.policy: fair -``` - -#### 使用本地版本库安装YuniKorn - -``` -Helm install yunikorn . --namespace yunikorn -``` - ---- - -## 设置Prometheus - -YuniKorn通过Prometheus公开其调度指标。 因此,我们需要设置一个Prometheus服务器来收集这些指标。 - -### 1. 下载Prometheus版本 - -``` -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` -``` -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. 配置prometheus.yml - -``` -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] - # 9080为内部端口,需要端口转发或修改9080为服务端口 -``` - -### 3. 启动Prometheus -``` -./prometheus --config.file=prometheus.yml -``` - ---- -## 运行测试 - -设置环境后,您就可以运行工作负载并收集结果了。 YuniKorn社区有一些有用的工具来运行工作负载和收集指标,更多详细信息将在此处发布。 - ---- - -## 收集和观察YuniKorn指标 - -Prometheus 启动后,可以轻松收集 YuniKorn 指标。 这是 YuniKorn 指标的[文档](metrics.md)。 YuniKorn 跟踪一些关键调度指标,这些指标衡量一些关键调度路径的延迟。 这些指标包括: - - - **scheduling_latency_seconds:** 主调度例程的延迟,以秒为单位。 - - **app_sorting_latency_seconds**: 所有应用程序排序的延迟,以秒为单位。 - - **node_sorting_latency_seconds**: 所有节点排序的延迟,以秒为单位。 - - **queue_sorting_latency_seconds**: 所有队列排序的延迟,以秒为单位。 - - **container_allocation_attempt_total**: 尝试分配容器的总次数。 尝试状态包括 `allocated`、`rejected`、`error`、`released`。 该指标仅增加。 - -您可以在Prometheus UI上轻松选择和生成图形,例如: - -![Prometheus Metrics List](./../assets/prometheus.png) - - ---- - -## 性能调优 - -### Kubernetes - -默认的 K8s 设置限制了并发请求,这限制了集群的整体吞吐量。 在本节中,我们介绍了一些需要调整的参数,以提高集群的整体吞吐量。 - -#### kubeadm - -设置pod网络掩码 - -``` -kubeadm init --pod-network-cidr=10.244.0.0/8 -``` - -#### CNI - -修改CNI掩码和资源。 - -``` - net-conf.json: | - { - "Network": "10.244.0.0/8", - "Backend": { - "Type": "vxlan" - } - } -``` -``` - resources: - requests: - cpu: "100m" - memory: "200Mi" - limits: - cpu: "100m" - memory: "200Mi" -``` - - -#### Api-Server - -在 Kubernetes API 服务器中,我们需要修改两个参数:`max-mutating-requests-inflight`和`max-requests-inflight`。 这两个参数代表API请求带宽。 因为我们会产生大量的Pod请求,所以我们需要增加这两个参数。修改`/etc/kubernetes/manifest/kube-apiserver.yaml`: - -``` ---max-mutating-requests-inflight=3000 ---max-requests-inflight=3000 -``` - -#### Controller-Manager - -在Kubernetes控制器管理器中,我们需要增加三个参数的值:`node-cidr-mask-size`、`kube-api-burst` `kube-api-qps`. `kube-api-burst`和`kube-api-qps`控制服务器端请求带宽。`node-cidr-mask-size`表示节点 CIDR。 为了扩展到数千个节点,它也需要增加。 - - -Modify `/etc/kubernetes/manifest/kube-controller-manager.yaml`: - -``` ---node-cidr-mask-size=21 //log2(集群中的最大pod数) ---kube-api-burst=3000 ---kube-api-qps=3000 -``` - -#### kubelet - -在单个工作节点中,我们可以默认运行110个pod。 但是为了获得更高的节点资源利用率,我们需要在Kubelet启动命令中添加一些参数,然后重启它。 - -修改`/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`中的起始参数,在起始参数后面添加`--max-Pods=300`并重启。 - -``` -systemctl daemon-reload -systemctl restart kubelet -``` - ---- - -## 概括 - -借助Kubemark和Prometheus,我们可以轻松运行基准测试、收集YuniKorn指标并分析性能。 这有助于我们识别调度程序中的性能瓶颈并进一步消除它们。 YuniKorn社区未来将继续改进这些工具,并继续获得更多的性能改进。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/profiling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/profiling.md deleted file mode 100644 index eb2ae74421a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/performance/profiling.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: profiling -title: 分析 ---- - - - -使用[pprof](https://github.com/google/pprof)做CPU,Memory profiling可以帮助你了解YuniKorn调度器的运行状态。YuniKorn REST服务中添加了分析工具,我们可以轻松地从HTTP端点检索和分析它们。 - -## CPU 分析 - -在这一步,确保你已经运行了YuniKorn,它可以通过`make run`命令从本地运行,也可以部署为在K8s内运行的pod。 然后运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/profile -``` - -配置文件数据将保存在本地文件系统中,一旦完成,它就会进入交互模式。 现在您可以运行分析命令,例如 - -``` -(pprof) top -Showing nodes accounting for 14380ms, 44.85% of 32060ms total -Dropped 145 nodes (cum <= 160.30ms) -Showing top 10 nodes out of 106 - flat flat% sum% cum cum% - 2130ms 6.64% 6.64% 2130ms 6.64% __tsan_read - 1950ms 6.08% 12.73% 1950ms 6.08% __tsan::MetaMap::FreeRange - 1920ms 5.99% 18.71% 1920ms 5.99% __tsan::MetaMap::GetAndLock - 1900ms 5.93% 24.64% 1900ms 5.93% racecall - 1290ms 4.02% 28.67% 1290ms 4.02% __tsan_write - 1090ms 3.40% 32.06% 3270ms 10.20% runtime.mallocgc - 1080ms 3.37% 35.43% 1080ms 3.37% __tsan_func_enter - 1020ms 3.18% 38.62% 1120ms 3.49% runtime.scanobject - 1010ms 3.15% 41.77% 1010ms 3.15% runtime.nanotime - 990ms 3.09% 44.85% 990ms 3.09% __tsan::DenseSlabAlloc::Refill -``` - -您可以键入诸如`web`或`gif`之类的命令来获得可以更好地帮助您的图表 -了解关键代码路径的整体性能。 你可以得到一些东西 -如下所示: - -![CPU Profiling](./../assets/cpu_profile.jpg) - -注意,要使用这些选项,您需要先安装虚拟化工具`graphviz`,如果您使用的是 Mac,只需运行`brew install graphviz`,更多信息请参考[这里](https://graphviz. gitlab.io/)。 - -## 内存分析 - -同样,您可以运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/heap -``` - -这将返回当前堆的快照,允许我们检查内存使用情况。 进入交互模式后,您可以运行一些有用的命令。 比如top可以列出top内存消耗的对象。 -``` -(pprof) top -Showing nodes accounting for 83.58MB, 98.82% of 84.58MB total -Showing top 10 nodes out of 86 - flat flat% sum% cum cum% - 32MB 37.84% 37.84% 32MB 37.84% github.com/apache/yunikorn-core/pkg/cache.NewClusterInfo - 16MB 18.92% 56.75% 16MB 18.92% github.com/apache/yunikorn-core/pkg/rmproxy.NewRMProxy - 16MB 18.92% 75.67% 16MB 18.92% github.com/apache/yunikorn-core/pkg/scheduler.NewScheduler - 16MB 18.92% 94.59% 16MB 18.92% github.com/apache/yunikorn-k8shim/pkg/dispatcher.init.0.func1 - 1.04MB 1.23% 95.81% 1.04MB 1.23% k8s.io/apimachinery/pkg/runtime.(*Scheme).AddKnownTypeWithName - 0.52MB 0.61% 96.43% 0.52MB 0.61% github.com/gogo/protobuf/proto.RegisterType - 0.51MB 0.61% 97.04% 0.51MB 0.61% sync.(*Map).Store - 0.50MB 0.6% 97.63% 0.50MB 0.6% regexp.onePassCopy - 0.50MB 0.59% 98.23% 0.50MB 0.59% github.com/json-iterator/go.(*Iterator).ReadString - 0.50MB 0.59% 98.82% 0.50MB 0.59% text/template/parse.(*Tree).newText -``` - -您还可以运行 `web`、`pdf` 或 `gif` 命令来获取堆图形。 - -## 下载分析样本并在本地进行分析 - -我们在调度程序docker映像中包含了基本的go/go-tool二进制文件,您应该能够进行一些基本的分析 -docker容器内的分析。 但是,如果您想深入研究一些问题,最好进行分析 -本地。 然后您需要先将示例文件复制到本地环境。 复制文件的命令如下: - -``` -kubectl cp ${SCHEDULER_POD_NAME}:${SAMPLE_PATH_IN_DOCKER_CONTAINER} ${LOCAL_COPY_PATH} -``` - -例如 - -``` -kubectl cp yunikorn-scheduler-cf8f8dd8-6szh5:/root/pprof/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -在本地环境中获取文件后,您可以运行“pprof”命令进行分析。 - -``` -go tool pprof /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -## 资源 - -* pprof 文档 https://github.com/google/pprof/tree/master/doc。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/acls.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/acls.md deleted file mode 100644 index fa480133424..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/acls.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: acls -title: ACLs ---- - - - -:::info -用户信息通过 [这里](usergroup_resolution) 定义的方法从 kubernetes shim 传递给 Yunikorn core。 -::: - -## 使用方法 -访问控制列表对 YuniKorn 来说是通用的。 -它们可以在 YuniKorn 的多个地方使用。 -目前的使用情况仅限于队列 ACL。 - -访问控制列表允许对列表中指定的用户和组进行访问。 -他们不提供明确删除或拒绝访问列表中指定的用户和组的可能性。 - -如果没有配置访问控制列表,默认情况下访问是 *拒绝* 的。 - -## 语法 -访问控制列表的定义如下: -``` -ACL ::= “*” | userlist [ “ “ grouplist ] -userlist ::= “” | user { “,” user } -grouplist ::= “” | group { “,” group } -``` - -这个定义指定了一个通配符 *,结果是每个人都可以访问。 - -如果用户列表为空,组列表为空,则没有人可以访问。 -拒绝所有的 ACL 有两种可能的表现形式: -* 一个空的访问控制列表。(隐式) -* 一个空格(显式) - - -## 示例配置 - -### 简单示例 -一个只允许用户 `sue` 访问的 ACL -```yaml - adminacl: sue -``` -其他人不会得到访问权,这仅适用于 `sue`。 -`john` 和 `bob` 将被拒绝访问。 - -一个允许用户 `sue` 和组 `dev` 成员访问的 ACL。 -```yaml - adminacl: sue dev -``` -用户 `sue` 根据她在ACL的用户部分的明确提及而获得访问权。 -尽管她不是 `dev` 组的成员。她的组员身份是不相关的。 - -名为 `john` 的用户是 `dev` 组的成员,他将被允许根据他的组员身份进行访问。 -第三个用户叫 `bob` ,他没有被明确提到,也不是 `dev` 组的成员,将被拒绝访问。 - -一个允许访问 `dev` 和 `test` 组成员的 ACL。 -```yaml - adminacl: " dev,test" -``` -ACL必须以空格开始,表示没有用户列表。 -如果ACL没有正确引用,空格会被 yaml 解析器删除。 -由于用户列表是空的,除非他们是 `dev` 或 `test` 组的成员,否则没有一个用户会得到访问权。 - -看一下和之前一样的三个用户: -用户 `sue` 不是任何一个组的成员,被拒绝访问。 -名为 `john` 的用户是 `dev` 组的成员,根据他的组员身份,他将被允许访问。 -`bob` 不是 `dev` 组的成员。由于其为 test 的成员,所以 `bob` 将被允许访问。 - -### 转义和引号 -ACL 目前是在队列配置中实现的,它使用一个 yaml 文件。 -这对如何转义值有一些限制。 -不正确的引号值将导致 yaml 解析错误,或者可能导致对值的不正确解释。 - -以下几点需要考虑到: -1. 通配符条目必须在 yaml 配置中加引号。 -1. 一个简单的用户列表,无论它后面是否有一个组的列表,都不需要加引号,但可以加引号。 -1. 一个没有用户列表,只有一个或多个组的 ACL 必须加引号,以找到起始空间: - -正确引用 ACL 的例子 -```yaml -partitions: - - name: default - queues: - - name: test - submitacl: "*" - adminacl: sue dev,test - - name: product - submitacl: " product" -``` - -## 访问检查 -访问检查遵循以下模式: -* 检查 ACL 是否是通配符 -* 检查该用户是否在用户列表中 -* 检查该用户所属的任何组是否是组列表的一部分 - -如果检查匹配,ACL 允许访问并停止检查。 -如果没有一个检查匹配,则 ACL 拒绝访问。 - -## 用户和组信息 -对于用户和组的解决,请遵循 [这里](usergroup_resolution) 定义的说明 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/deployment_modes.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/deployment_modes.md deleted file mode 100644 index b33e1502aa1..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/deployment_modes.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -id: deployment_modes -title: 部署模式 ---- - - - -## YuniKorn部署模式 - -YuniKorn有两种部署模式: `标准模式`与`插件模式`。 -在标准模式下,YuniKorn作为自定义模式运行Kubernetes调度程序。 -在插件模式下,YuniKorn被实现为默认Kubernetes调度框架之上的一组插件。 - -在这两种情况下,建议同时运行准入控制器(admin controller),这会确保只有一个调度程序在您的Kubernetes集群中处于活动状态。 -当准入控制器运行时,所有pod将会绕过Kubernetes的默认调度器,除了YuniKorn本身的pod。 - -## 应该使用哪个版本? - -### 标准模式(Standard) - -目前的默认模式是标准模式。 标准模式提供稳定、高效、良好性能。 -当pod利用YuniKorn的队列功能,此模式非常适合大多数此类部署。 - -### 插件模式(Plugin) - -插件模式是一种新的部署模型,调度器是在默认的Kubernetes调度逻辑之上实现的,可以更好地兼容默认的Kubernetes调度器。 -它非常适合混合工作负载,如传统的Kubernetes以及排队的应用程序。 - -插件模式目前非常新,因此还没有达到标准模式的成熟度。 - -要在使用 Helm 部署时激活插件模式,请将变量`enableSchedulerPlugin`设置为`true`。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/gang_scheduling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/gang_scheduling.md deleted file mode 100644 index e7e30526d6e..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/gang_scheduling.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -id: gang_scheduling -title: 分组调度 ---- - - - -## 什么是分组调度 - -当分组调度被启用时,YuniKorn 只在以下情况下调度应用程序 -应用程序的最小资源请求能够得到满足时才会调度。否则,应用程序 -将在队列中等待。应用程序被排在层次队列中、 -启用分组调度后,每个资源队列都被分配有 -在保证最小资源的情况下,每个资源队列都被分配了最大数量的应用程序并发运行。 - -![分组调度](./../assets/gang_scheduling_intro.png) - -## 启用分组调度 - -启用分组调度不需要在集群范围内进行配置。 -调度器会主动监控每个应用的元数据,如果该应用包含了 -一个有效的任务组定义,它就会被认为是所需的分组调度。 - -:::info 任务组 -一个任务组是一个应用程序中的任务 "群组",这些任务具有相同的资源概况 -和相同的放置限制。它们被认为是同质化的请求,在调度器中可以被视为 -在调度器中被当作同一类请求处理。 -::: - -### 前提 - -对于运行支持调度的应用程序的队列,队列排序策略应该被设置为 "FIFO"。 -要配置队列排序策略,请参考文档:[应用程序排序](user_guide/sorting_policies.md#应用程序排序)。 - -#### 为什么要使用 "FIFO" 排序策略? - -当分组调度被启用时,调度器会主动为每个应用程序保留资源。 -如果队列排序策略不是基于FIFO(StateAware 是基于 FIFO 的排序策略)、 -调度器可能会为每个应用保留部分资源并导致资源分割问题。 - -#### "StateAware" 排序策略的副作用 - -我们不建议使用 `StateAware`,尽管它是一个基于 FIFO 的策略。第一个 pod 的失败或者该 pod 的初始化时间过长都会使处理过程变慢。 -当驱动在请求执行器之前进行大量的预处理时,尤其是 Spark。 -在这些情况下,`StateAware` 超时会使处理速度减慢到每次超时只有一个应用程序。 -这实际上会推翻群组的保留,并导致减速和过度使用资源。 - -### 应用程序配置 - -在 Kubernetes 上,YuniKorn 通过从单个pod加载元数据来发现应用,应用的第一个pod -被要求附上一份完整的应用元数据副本。如果应用程序没有关于第一个或第二个pod的任何注释, -那么所有的pod都需要携带相同的 taskGroups 信息。分组調度需要 taskGroups 的定义, -可以通过 pod 注解来指定。所需的字段是: - -| 注释 | 价值 | -|-----|------| -| yunikorn.apache.org/task-group-name | 任务组名称,在应用程序中必须是唯一的。 | -| yunikorn.apache.org/task-groups | 任务组的列表,每一项都包含了为该任务组定义的所有信息。 | -| yunikorn.apache.org/schedulingPolicyParameters | 可选。一个任意的键值对来定义调度策略参数。请阅读[调度策略参数](#调度策略参数) | - -#### 需要多少个任务组? - -这取决于这个应用程序向 K8s 请求多少不同类型的 pod。一个任务组是一个应用程序中的任务 "群组"、 -这些任务具有相同的资源概况和相同的放置限制。它们被认为是同质的 -在调度器中可以被视为同类的请求。以 Spark 为例,每个作业都需要有2个任务组、 -一个用于driver pod,另一个用于 executor pods。 - -#### 如何定义任务组? - -任务组的定义是应用程序的真实pod定义的副本,像资源、节点选择器、容忍度 -和亲和力应该与真正的pod相同。这是为了确保调度器能够以准确的pod规格保留资源。 -确切正确的pod规范。 - -#### 调度策略参数 - -调度策略相关的可配置参数。在pod的注释中以下列格式应用这些参数: - -```yaml -annotations: - yunikorn.apache.org/schedulingPolicyParameters: "PARAM1=VALUE1 PARAM2=VALUE2 ..." -``` - -目前,支持以下参数: - -`placeholderTimeoutInSeconds` - -默认值: *15分钟*。 -这个参数定义了预约超时,即调度器在放弃分配所有占位符之前应该等待多长时间。 -当调度器*分配第一个占位器pod*时,超时计时器开始计时。这确保了如果调度器 -无法调度所有的占位荚,它最终会在一定的时间后放弃。这样,资源可以被 -释放出来,供其他应用程序使用。如果没有占位符可以被分配,这个超时就不会启动。为了避免占位符 -pods永远卡住,请参考 [故障排除](troubleshooting.md#成组调度) 了解解决方案。 - -`gangSchedulingStyle` - -有效值: *Soft*, *Hard* - -默认值:*Soft*. -这个参数定义了当应用程序由于占位符 pod 分配而遇到分组问题时的后退机制。 -更多细节见[分组调度风格](#分组调度风格)部分 - -更多的调度参数将被添加,以便在调度应用程序时提供更多的灵活性。 - -#### 示例 - -下面的例子是一个工作的yaml文件。这个工作启动了2个 pod,每个 pod 睡眠时间为 30 秒。 -在 pod 规范中值得注意的变化是 *spec.template.metadata.annotations*,在这里我们定义了 `yunikorn.apache.org/task-group-name` -和 `yunikorn.apache.org/task-groups` 。 - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-scheduling-job-example -spec: - completions: 2 - parallelism: 2 - template: - metadata: - labels: - app: sleep - applicationId: "gang-scheduling-job-example" - queue: root.sandbox - annotations: - yunikorn.apache.org/task-group-name: task-group-example - yunikorn.apache.org/task-groups: |- - [{ - "name": "task-group-example", - "minMember": 2, - "minResource": { - "cpu": "100m", - "memory": "50M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "50M" -``` - -当这项工作提交给 Kubernetes 时,将使用同一模板创建2个pod,它们都属于一个任务组: -*"task-group-example"*。 YuniKorn将创建2个占位符pod,每个都使用任务组定义中指定的资源。 -当所有2个占位符分配完毕后,调度器将使用占位符保留的位置来绑定真正的2个睡眠pods。 - -如果有必要,你可以添加多个任务组,每个任务组由任务组名称标识、 -通过设置任务组名称,需要将每个真实的pod与一个预先定义的任务组进行映射。注意、 -任务组名称只要求在一个应用程序中是唯一的。 - - -### 启用Spark作业的Gang调度 - -每个Spark作业都运行2种类型的pod,驱动和执行器。因此,我们需要为每个作业定义2个任务组。 -驱动器pod的注释看起来像: - -```yaml -Annotations: - yunikorn.apache.org/schedulingPolicyParameters: “placeholderTimeoutSeconds=30” - yunikorn.apache.org/taskGroupName: “spark-driver” - yunikorn.apache.org/taskGroup: “ - TaskGroups: [ - { - Name: “spark-driver”, - minMember: 1, - minResource: { - Cpu: 1, - Memory: 2Gi - }, - Node-selector: ..., - Tolerations: ..., - Affinity: ... - }, - { - Name: “spark-executor”, - minMember: 10, - minResource: { - Cpu: 1, - Memory: 2Gi - } - } - ] - ” -``` - -:::note -任务组的资源必须考虑到Spark驱动和执行器的内存开销。 -参见 [Spark documentation](https://spark.apache.org/docs/latest/configuration.html#application-properties) 以了解如何计算这些数值的细节。 -::: - -对于所有的执行者 pod, - -```yaml -Annotations: - # 任务组字段中定义的名称相匹配 - # 在任务组字段中定义 - yunikorn.apache.org/taskGroupName: “spark-executor” -``` - -一旦工作被提交给调度器,工作就不会被立即调度。 -相反,在实际启动驱动/执行器之前,调度器将确保它获得最小的资源。 - -## 分组调度风格 - -有2种分组调度方式支持,分别是 Soft 和 Hard。它可以在每个应用层面进行配置,以定义应用在分组调度失败时的行为。 - -- `Hard Style`:当使用这种风格时,我们将有初始行为,更确切地说,如果应用程序不能根据分组调度规则进行调度,并且超时,它将被标记为失败,而不会重新尝试调度。 -- `Soft Style`:当应用程序不能被分组调度时,它将退回到正常的调度,并使用非分组调度策略来实现最佳努力的调度。当这种情况发生时,应用程序将过渡到恢复状态,所有剩余的占位符 pod 将被清理掉。 - -**使用的默认样式**: `Soft`。 - -**启用一个特定的风格**:可以通过在应用程序定义中设置'gangSchedulingStyle'参数来改变风格,即 Soft 或 Hard。 - -#### Example - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-app-timeout -spec: - completions: 4 - parallelism: 4 - template: - metadata: - labels: - app: sleep - applicationId: gang-app-timeout - queue: fifo - annotations: - yunikorn.apache.org/task-group-name: sched-style - yunikorn.apache.org/schedulingPolicyParameters: "placeholderTimeoutInSeconds=60 gangSchedulingStyle=Hard" - yunikorn.apache.org/task-groups: |- - [{ - "name": "sched-style", - "minMember": 4, - "minResource": { - "cpu": "1", - "memory": "1000M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - imagePullPolicy: "IfNotPresent" - command: ["sleep", "30"] - resources: - requests: - cpu: "1" - memory: "1000M" - -``` - -## 验证配置 - -为了验证配置是否已经完全正确,请检查以下事项: -1. 当一个应用程序被提交时,验证预期的占位符数量是否被调度器创建。 -如果你定义了两个任务组,一个是minMember 1,另一个是minMember 5,这意味着我们期望在任务提交后有6个占位符被创建。 -被创建。 -2. 验证占位符的规格是否正确。每个占位符都需要有与同一任务组中的真实pod相同的信息。 -检查领域包括:命名空间、pod资源、节点选择器、容忍度和亲和力。 -3. 验证占位符可以分配到正确的节点类型上,并验证真正的pod是通过替换占位符pod而启动的。 - -## 故障排除 - -请参阅启用帮派调度时的故障排除文档 [這裡](troubleshooting.md#成组调度) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/labels_and_annotations_in_yunikorn.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/labels_and_annotations_in_yunikorn.md deleted file mode 100644 index 5279422dbb9..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/labels_and_annotations_in_yunikorn.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -id: labels_and_annotations_in_yunikorn -title: 标签和注释 ---- - - -## YuniKorn 中的标签和注释 -YuniKorn 利用了几个 Kubernetes 标签和注释来支持各种功能: - -### YuniKorn 的标签 -| 名称 | 说明 | -|----------------------|-------------------------------------------------------------------------------------------------------| -| `applicationId` | 将这个 Pod 与一个应用程序联系起来。 | -| `queue` | 选择这个应用程序应该被安排在哪个 YuniKorn 队列中。如果有放置策略,这可能被忽略。 | -| `spark-app-selector` | 如果标签 `applicationId` 和注解 `yunikorn.apache.org/app-id` 未设置,Spark Operator 使用的指定 `applicationId` 的替代方法。 | -| `disableStateAware` | 如果存在,则禁用该 pod 的 YuniKorn 状态感知调度策略。由 YuniKorn 接纳控制器内部设置。 | -| `placeholder` | 设置该 pod 是否代表分组调度的占位符。由 YuniKorn 内部设置。 | - -### YuniKorn 中的注解 -所有注解都在 `yunikorn.apache.org` 的命名空间下。例如 `yunikorn.apache.org/app-id` 。 - -| Name | Description | -|------------------------------|------------------------------------------------------------------------------------------------------------------------------------------| -| `app-id` | 将这个pod与一个应用程序联系起来。
应用ID的优先级由以下因素决定:注释 `yunikorn.apache.org/app-id` > 标签 `applicationId` > 标签 `spark-app-selector`。 | -| `queue` | 选择这个应用程序应该被安排在YuniKorn队列中。
队列的优先级由以下因素决定:标签 `queue` >注释 `yunikorn.apache.org/queue` >默认。 | -| `task-group-name` | 设置这个pod所属的任务组名称,以便进行分组调度。它必须列在`task-groups`中。 | -| `task-groups` | 定义了这个应用程序的任务组集合,用于分组调度。一个应用程序中的每个pod必须定义所有的任务组。 | -| `schedulingPolicyParameters` | 任意的键值对,用于定制调度策略,如分组调度。 | -| `placeholder` | 设置该pod是否代表分组调度的占位符。由YuniKorn内部设置。 | -| `allow-preemption` | `allow-preemption'注解只能设置在PriorityClass对象上。它将触发对具有该特定优先级类的pod的选择退出抢占。进一步的细节可以在[使用简单的抢占器进行 DaemonSet 调度](../design/simple_preemptor)文档中找到。 | -| `parentqueue` | 为一组K8s命名空间定义一个父队列。进一步的细节可以在[资源配额管理](resource_quota_management#命名空间的父队列映射)文档中找到。 | -| `namespace.quota` | 设置映射到该命名空间的队列的最大容量。进一步的细节可以在[资源配额管理](resource_quota_management#命名空间配额)文档中找到。 | -| [已删除] `namespace.max.cpu` | 从1.2.0版开始,用 `namespace.quota` 代替。 | -| [已删除] `namespace.max.memory` | 自1.2.0版起被`namespace.quota`取代。 | -| `namespace.enableYuniKorn` | 控制哪些命名空间的pod将被转发给Yunikorn进行调度。进一步的细节可以在[服务配置#准入控制器过滤设置](service_config#准入控制器过滤设置)文档中找到。 | -| `namespace.generateAppId` | 控制哪些命名空间将有标有 `applicationId` 的 pod。进一步的细节可以在[服务配置#准入控制器过滤设置](service_config#准入控制器过滤设置)文档中找到。 | - -关于分组调度的标签和注释的更多细节,请参考[分组调度](../user_guide/gang_scheduling.md)的文档。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/placement_rules.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/placement_rules.md deleted file mode 100644 index 17ccd279c87..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/placement_rules.md +++ /dev/null @@ -1,296 +0,0 @@ ---- -id: placement_rules -title: App 放置规则 ---- - - -基础的放置规则(placement rules)配置[调度弃配置设计文档](../design/scheduler_configuration#placement-rules-definition)中有相关描述。 - -我们可以将多个规则链结再一起形成一个放置策略,并通过[存取控制列表(Access control lists)](user_guide/acls.md)和规则过滤来定义和执行规则。 - -本篇文章将通过例子来解释如何建立策略以及规则的使用,而该放置策略为调度器的一部分。 - -## 配置 -放置规则作为调度程序队列配置的一部分,可以在各分区(partition)中被定义。规则定义的顺序就是他们会被执行的顺序。如果一个规则匹配,策略会停止执行剩余的规则。 - -匹配的放置规则会产生一个完全合格的队列名称。同时这个回传的队列名称会从根队列(root)开始。而在队列层次结构中,可以生成的层次数量没有限制。 - -当要执行一条规则时,已经被执行过的规则不会被列入考虑;这条规则也不会对往后要执行的规则有所影响:规则不能影响其他的规则,除非它们被配置为父规则([parent](#parent-参数))。 - -当放置策略没有生成队列名称且没有更多的规则时,应用程式将会被拒绝。 - -在配置中,定义放置规则的基本结构如下: -```yaml -placementrules: - - name: <第一条放置规则的名称> - - name: <第二条放置规则的名称> -``` -每个[规则](#规则)都可以在配置中采取一套预定义的参数。可以被使用的规则名称在规则描述中提及。规则名称在配置中不区分大小写,且必须遵从以下的命名惯例: -* 从字母开始:a-z 或 A-Z -* 后面跟着0或多个字元 a-z, A-Z, 0-9 或 _ - -当规则名称没有对应到任何已定义的规则时,表示规则处于未知的状态,会造成放置管理器初始化错误。如果参数不正确,会抛出解析错误或在初始化时发生错误。一个有错误的规则集永远不可能被激活。 - -如果放置管理器中含有一个被激活的规则集,就代表他已经初始化了。重新载入时,若配置了一个新的规则集时,就会将新的规则集激活,并取代旧有的。如果新规则集包含一个错误,放置管理器就会忽视这个新规则集,同时也持续处于「使用不完全的规则集」的状态。如果放置管理器持续使用已激活的规则集,忽视新的且有错误的规则集时,则会记录一条关于坏掉且被忽视的配置信息。 - -规则结果中的「点 "."」,会被文字的「"\_dot\_"」所替代。而「点」会被取代是因为在完全限定的队列名称中,他是被用来分隔队列层次的。而替代过程是发生在建构完整队列层次,且结果合格之前。这代表我们允许用「点」来表达用户名或标籤值,但不影响到队列层次。举例来说,当配置中的队列对应到「含有点的用户名」时,你必须要使用以下方法来指定它们:如果一个用户名称为`user.name`且使用`user`规则,则会产生队列名称为`root.user_dot_name`的队列。而如果该用户队列必须事先被加到配置中,则也该使用`user_dot_name`这个名字。 - -### Create 参数 -create 参数是一个布林值,会定义当一个队列不存在时,是否可以在规则的定义下创建队列。不能保证队列一定会被创建,因为现有的队列可能会阻止创建。但如果规则定义下想创建的队列不存在,且`create: false`,那结果将会是创建失败。 - -带有`create`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - create: true -``` -预设值为`false`。允许的值为`true`或`false`,其他值均会导致显示错误。 - -### Parent 参数 -`parent` 参数允许指定一个规则,并为他产生一个父队列。父规则可以被嵌套,一个父规则可以包含另一个父规则,此外对于父规则的嵌套也没有强制限制。 - -父规则被视为顶层的规则,因此具有与放置定义中任何其他规则相同的参数和需求。例外的情况是,在「已经生成完全合格队列」的规则上再使用父规则,被认为是一个配置错误。这个错误只能发生在`fixed`型的规则上,查看规范可以得到更多细节。 - -注意:规则的执行会沿着父规则的列表向下遍历,并首先执行列表中的最后一条。代表最后一条父规则将会直接产生在根部,详见示例。 - -带有`parent`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - parent: - name: <父规则的名称> -``` -预设值中没有parent参数。 - -### Filter 参数 -通过`filter`参数的定义,能过滤掉适用的用户来进行配置。过滤器是一个复杂的配置組件。 - -用户和群组可以被配置为两种类别: -* 正则表达式 -* 用户或群组的列表 - -如果用户或群组在yaml中的条目超过一个,则就会被视为一个用户列表或群组列表。列表中重复的条目会被忽略,不会引起错误。依据其他列表元素来使用正则表达式是不被允许的。 - -用户和群组名称遵循标准的Linux 用户和群组惯例,对于用户名来说: -* 从一个字母作为开头:a-z 或 A-Z -* 后面跟着0或更多个字符:a-z, A-Z, 0-9 或 _ . @ - -* 最后一个字符可以式$ - -对于群组名来说: -* 从一个字母作为开头:a-z 或 A-Z -* 后面跟着0或更多个字符:a-z, A-Z, 0-9 或 _ - - -如果列表中正好有一个条目,他可以是单个用户、群组或正则表达式。当一个条目包含一个在用户或群组中不允许的字符时,该条目会被认为是一个正则表达式。正则表达式必须按照规定进行编译。一个不能编译的正则表达式将会被忽略。 - -此外针对群组的正则表达式中:每次都是针对一个组进行匹配,而不是针对组的列表。 - -带有 `filter`参数的简易yaml范例: -```yaml -filter: - type: deny - users: - - - - - groups: - - - - -``` -预设值中没有filter参数。 - -### Value 参数 -这是一个通用值,用来传递给规则以实现或改变其行为。该值被用来与[fixed](#fixed-rule)和[tag](#tag-rule)型的规则一起使用。此外`value`是以字串型式存在的单一值,也不会被系统解释或干扰。 - -带有 `value`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - value: "any string" -``` -预设值中没有value参数。 - -## 准入控制列表 -准入控制列表没有在规则中定义,但它们影响放置策略的结果。有两种准入控制列表可以被定义到队列上: -1. 提交ACL: `submitacl` -2. 管理ACL: `adminacl` - -如果队列的ACL允许任何ACL提交存取,则放置规则才能匹配。管理队列ACL还提供「提交准入」的功能。如果队列不存在或没有配置ACL,则将检查父队列的ACL。这种递迴的检查会重复执行,直到有ACL提供存取或根目录的ACL被检查过后。 - -关于ACL语法的更多细节,请查阅[ACL文档](user_guide/acls.md)。 - -## 规则 -### Provided Rule -在配置中使用的名称:*provided* - -提供在提交应用时所指定的队列。本规则的行为是─如果队列不完全合格,则完全限定由「应用程序提供的队列」作为放置的队列。如果设置了一个父规则,并且在应用程序提交中提供的队列是完全合格的,那麽父规则就不会被执行。 - -支持的参数: -* create -* parent -* filter - -举例:如果用户名下不存在队列,则用户传入的队列会被创建。 -```yaml -placementrules: - - name: provided - create: true - parent: - name: user - create: true -``` -当用户 `developer` 向应用程式提交请求,且应用程式要求的队列名称为:`my_special_queue`。
-结果:`root.developer.my_special_queue`(父规则将设置用户名称)。 - -当用户 `developer` 向应用程式提交请求,且应用程式要求的队列名称为:`root.dev_queue`。
-结果:`root.dev_queue`(父规则将被忽视)。 - -### User Name Rule -在配置中使用的名称:*user* - -提供一个基于用户名的队列,而该用户名为所提交的应用程序的一部分。 - -支持的参数: -* create -* parent -* filter - -举例:提交一个基于用户名的队列,如果队列不存在,不要创建队列。 -```yaml -placementrules: - - name: user - create: false -``` - -当用户`finance.test`提交了一个应用程式,此外对应的队列也存在。
-结果: `root.finance_dot_test`(注意,「点」被替换了)。 - -当用户`developer`提交了一个应用程式,但对映的队列不存在。
-结果:失败,执行下一条规则。 - -### Fixed Rule -在配置中使用的名称:*fixed* - -回传一个队列,其依据规则参数的值作为名称,配置的值必须是一个合法的队列名称或层次结构。该队列名称不一定需要完全合格。名称中的层次结构使用「一个点(.)」作为层次结构中不同级别的分隔符。只有当配置的队列不存在且`create`标籤未设置时,`fixed`规则才会失败,因为他始终新增一个配置的队列。 - -支持的参数: -* value(reuqired) -* create -* parent -* filter - -举例:因为总是会回传一个队列,若没有设置`create`标籤,则要在配置中将队列定义为子队列。 -```yaml -placementrules: - - name: fixed - value: last_resort -``` - -当用户 `developer`提交请求,且在应用程式中设定的队列为:`my_special_queue` 。
-结果:`root.last_resort`。 - -### Tag Rule -在配置中使用的名称:*tag* - -从应用程式的标籤中检索队列名称。检查`tag`的值(value),并在规则中使用该值进行配置。若`tag`规则没有包含任何值,则代表配置错误,但是一个应用程式不一定要设置该值。 - -如果应用程序上没有设置对应的`tag`,则规则失败。如果从应用程序回传的`tag` value是一个完全限定的队列名称,则父规则(如果已配置)将不会执行。 - -支持的参数: -* value(reuqired) -* create -* parent -* filter - -举例:根据kubernetes命名空间放置一个应用程序,该命名空间在提交时自动在应用程序中设置。 -```yaml -placementrules: - - name: tag - value: namespace - create: true -``` - -用户`developer`在命名空间`default`,提交基于kubernetes的应用程序请求,且在应用程是中设定的队列为:`my_pecial_queue`。
-结果:`root.default`。 - -用户`developer`在命名空间`testing`,提交基于kubernetes的应用程序请求,且在应用程是中设定的队列为:`my_pecial_queue`。
-结果:`root.testing`。 - -用户提交非基于kubernetes的应用程序请求。
-结果:失败,执行下一条规则。 - -## 复杂的例子 -在这个复杂的例子中,我们串连了三个规则: - -1. 一个`user`规则,其父规则标籤使用kubernetes命名空间,且仅供`dev`群组内的用户。 -2. 一个`tag`规则,使用kubernetes命名空间,其`parent`规则固定使用已存在的队列─ `root.namespaces`。 -3. 一个`fixed`规则,将所有到达这个点的应用程序都放在`root.default`队列中。 - -举例: -```yaml -placementrules: - - name: user - create: true - filter: - type: allow - groups: - - dev* - parent: - - name: tag - value: namespace - - name: tag - value: namespace - create: true - parent: - - name: fixed - value: root.namespaces - filter: - type: allow - users: - - john - - name: fixed - value: root.default -``` -用户`john`在命名空间testing中提交基于kubernetes应用程序的请求。
-结果:`root.namespaces.testing`(在规则2中匹配)。 - -用户`sarah`在命名空间`newapp`中提交基于kubernetes应用程序的请求,组员为`sarah`, `test_app`, `dev_app`。
-结果:`root.newapp.sarah`(在规则1中匹配)。 - -用户bob在命名空间`testapp`中提交基于kubernetes应用程序的请求,组别成员为`bob`。
-结果:`root.default`(在规则3中匹配)。 -
-在第二个例子中,我们使用了两条规则。 - -1. 一个`fixed`规则,将所有东西放在`root.production`队列中。 -2. 一个`user`规则,以及设置 `create` 标籤。 - -但在这个例子中,我们在`root.production`的队列上设置了ACL,只允许两个特定的用户使用这个队列。因此,即使规则匹配,除非是`john`或`bob`,否则应用程式将不会被放在`production`队列中。所有其他用户将匹配第二条规则并使用它们自己的队列,如果队列不存在,就会创建。 - -```yaml -partitions: - - name: default - queues: - - name: production - submitacl: john,bob - placementrules: - - name: fixed - value: root.production - - name: user - create: true -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/prometheus.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/prometheus.md deleted file mode 100644 index 4ded82ff1f1..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/prometheus.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: prometheus -title: Setting Prometheus ---- - - - -YuniKorn exposes its scheduling metrics via Prometheus. Thus, we need to set up a Prometheus server to collect these metrics. - -If you don't know what metric can be used, you can use [REST API](../api/scheduler.md#指标(Metrics)). - -### 1. **Download Prometheus release** - -```bash -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` - -```bash -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. **Configure prometheus.yml** - -Prometheus collects metrics from *targets* by scraping metrics HTTP endpoints. - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['localhost:9080'] - # 9080 is internal port, need port forward or modify 9080 to service's port -``` - -### 3. Start port-forward - -Port forwarding for the core's web service on the standard port can be turned on via: - -```bash -kubectl port-forward svc/yunikorn-service 9080:9080 -n yunikorn -``` - -`9080`is the default port for core's web service. - -### 4. Execute prometheus - -```bash -./prometheus --config.file=prometheus.yml -``` - -![prometheus-cmd](../assets/prometheus-cmd.png) - -### 5. Access the Prometheus UI - -You should be able to browse to a status page at [localhost:9090](http://localhost:9090/). Give it a couple of seconds to collect data about itself from its own HTTP metrics endpoint. - -![prometheus-web-ui](../assets/prometheus-web-ui.png) - -You can also verify that Prometheus is serving metrics by navigating to its metrics endpoint:[localhost:9090/metrics](http://localhost:9090/metrics) \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/queue_config.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/queue_config.md deleted file mode 100644 index 3b9b7672a81..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/queue_config.md +++ /dev/null @@ -1,379 +0,0 @@ ---- -id: queue_config -title: 分区和队列配置 ---- - - - -队列配置基础在[配置设计文档](design/scheduler_configuration.md)中有描述。 - -本文档提供通用队列配置。 -队列配置引用了[访问控制列表](user_guide/acls.md)和[放置规则](user_guide/placement_rules.md)文档。 - -本文档通过示例说明如何为调度程序创建分区和队列配置。 - -调度程序依靠shim可靠地提供用户信息作为应用程序提交的一部分。 -当前shim使用[用户和组解析](usergroup_resolution)中提供的方法识别用户和用户所属的组。 - -## 配置 -此处描述的调度器的配置文件仅提供分区和队列的配置。 - -默认情况下,我们在部署中使用`queues.yaml`文件。 -文件名可以通过命令行更改调度器的`policyGroup`标志。 -更改文件名后必须对部署细节进行相应的更改,可以是`configmap`或包含在docker容器中的文件。 -配置的示例文件位于yunikorn-core的[queues.yaml](https://github.com/apache/yunikorn-core/blob/master/config/queues.yaml). - -## 分区 -分区(partitions)是调度器配置的最高级别。 -在配置中可以定义多个分区。 - -配置中分区定义的基本结构如下: -```yaml -partitions: - - name: <第一个分区的名称> - - name: <第二个分区的名称> -``` -分区的默认名称是`default`。 -分区定义包含特定shim相应调度器的完整配置。 -每个shim都使用自己独特的分区。 - -分区必须至少需要定义以下键: -* name -* [queues](#队列) - -队列配置会在分区结束后介绍。 - -可以选择为分区定义以下键: -* [placementrules](#放置规则) -* [statedumpfilepath](#状态转储文件路径) -* [limits](#限制) -* nodesortpolicy -* preemption - -放置规则和限制在各自的章节中解释。 - -`nodesortpolicy`定义节点为分区排序的方式。 -有关可以使用的节点排序策略值的详细信息,请参阅[排序策略](user_guide/sorting_policies.md#node-sorting)文档。 - -抢占键目前只能有一个子键: _enabled_。 -这个布林值定义了整个分区的抢占行为。 - -_enabled_的默认值为_false_。 -_enabled_的允许值:_true_或_false_,任何其他值都会导致解析错误。 - -下方的示例中,`partition` yaml条目是带有_preemption_标志集和_fair_的`nodesortpolicy`。 -```yaml -partitions: - - name: <分区名称> - nodesortpolicy: fair - preemption: - enabled: true -``` -备注: -目前,Kubernetes独特的shim不支持除`default`分区之外的任何其他分区。 -这已被记录为shim的[jira](https://issues.apache.org/jira/browse/YUNIKORN-22)。 - -### 队列 - -YuniKorn通过利用资源队列来管理资源。 -资源队列(queues)具有以下特征: -- 队列可以有**层次**结构 -- 每个队列都可以预设**最小/最大容量**,其中最小容量定义保证资源,最大容量定义资源限制(所谓的资源配额) -- 任务必须在某个`leaf`队列下运行 -- 队列可以是**静态**(从配置文件加载)或**动态**(由YuniKorn内部管理) -- 队列级别的**资源公平**是由调度器强制执行 -- 作业只能在特定队列下运行 - -:::info -YuniKorn队列与[Kubernetes命名空间](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)的区别: -Kubernetes命名空间提供了Kubernetes资源的范围,包括安全环境(即谁可以访问对象),以及定义[资源配额](https://kubernetes.io/docs/concepts/policy/resource-quotas/)时的资源边界(即对象可以使用多少资源)。 -另一方面,YuniKorn队列仅使用一组作业可以使用多少资源,以及以何种顺序使用。 -YuniKorn队列在考虑资源公平性、作业排序等方面提供了更细粒度的多租户资源共享控制。 -在大多数情况下,YuniKorn队列可用于替代命名空间资源配额,以提供更多的调度特性。 -::: - -_queues_条目是主要的配置元素,它为队列定义了层次结构。 - -它可以定义一个`root`队列,但它不是必需的元素。 -如果未定义`root`队列,配置解析将插入root队列以保持一致性。 -以下因素会触发root队列的插入: -* 如果配置在顶层定义了多个队列,则会插入一个根队列。 -* 如果在顶层只定义了一个队列并且它不被称为`root`,则插入一个root队列。 - -定义的一个或多个队列将成为插入的`root`队列的子队列。 - -带有子队列的基本`queue` yaml条目: -```yaml -queues: -- name: <队列名称> - queues: - - name: <队列名称> -``` - -队列支持的参数: -* name -* parent -* queues -* maxapplications -* properties -* adminacl -* submitacl -* [resources](#资源) -* [limits](#限制) - -每个队列都必须有一个_name_并且队列的名称在定义队列的同一级别上必须是唯一的。 -由于队列结构是完全层次化的,层次结构中不同点的队列可能具有相同的名称。 -例如:队列结构`root.testqueue`和`root.parent.testqueue`是一个有效的结构。 -需注意的是,队列不能包含点“.”字符,因为该字符用于分隔层次结构中的队列。 -如果名称对于配置中的队列不是唯一的,或者名称包含一个点,则会生成解析错误并拒绝配置。 - -依队列的类型是否于队列有子模板队列和子队列的事实,结构中的队列将自动获得分配的类型。 -队列类型有两种: -* parent -* leaf - -应用只能分配给_leaf_队列。 -在配置中,队列具有子模板队列或子队列将自动成为_parent_队列。 -如果队列在配置中没有子队列,则该队列是_leaf_队列,除非该队列`parent`参数设置为_true_。 -尝试覆盖配置中的_parent_队列类型将导致配置解析错误。 - -parent队列的子队列在`queues`条目下定义。 -`queues`条目是队列级别的递归条目,它使用完全相同的参数集。 -_maxapplications_属性是一个大于 1 的整数值,它允许您限制队列中正在运行的应用的数量。 -不允许为_maxapplications_指定零,因为它会阻止队列中应用的任何分配。 -_子_队列的_maxapplications_值必须小于或等于_parent_队列的值。 -`properties`参数是一个简单的键值对列表,并为队列提供一组简单的属性。其中的键或值没有限制,任何东西都是允许的。 -目前,属性列表仅在调度器中用于定义leaf队列的[排序顺序](user_guide/sorting_policies.md#application-sorting)。 -在未来的扩展中,添加比如打开或关闭队列抢占或其他排序策略的选项,让使用相同的属性构造而无需更改配置。 - -通过`adminacl`设置对队列的访问权限以进行管理操作,并通过`submitacl`条目提交应用。 -访问控制列表(ACLs)的描述可见[访问控制列表(ACLs)](user_guide/acls.md)文档。 - -队列资源限制是通过`resources`参数设置。 -用户和群组的限制是通过`limits`参数设置。 -由于这两个条目都是复杂的配置条目,因此它们在下面的[resources](#资源)和[limits](#限制)中有相应解释。 - -以下示例配置是`root.namespaces`队列作为具有限制的_parent_队列: -```yaml -partitions: - - name: default - queues: - - name: namespaces - parent: true - maxapplications: 12 - resources: - guaranteed: - {memory: 1G, vcore: 10} - max: - {memory: 10G, vcore: 100} - queues: - - name: level1 - maxapplications: 8 - resources: - guaranteed: - {memory: 0.5G, vcore: 5} - max: - {memory: 5G, vcore: 50} -``` - -### 放置规则 - -放置规则(placement rules)在[放置规则](user_guide/placement_rules.md)文档中有相关定义和记录。 - -每个分区只能定义一组放置规则。 -如果没有定义规则,则放置管理器不会启动。 -此外,在提交应用时,*必须*为每个应用设置一个队列。 - -### 状态转储文件路径 - -状态转储文件路径(Statedump filepath)定义YuniKorn状态转储的输出文件并且它可以在分区级别上设置。 -如果设置转储文件路径,该字段的值可以是相对路径或绝对路径(此处相对路径是基于工作目录)。 -如果YuniKorn调度器没有足够的权限在指定路径创建状态转储文件,它将无法启动状态转储的功能。 - -```yaml -statedumpfilepath: -``` -如果上面的键没有在分区配置中指定,它的默认值为`yunikorn-state.txt`。 -需注意的是,如果键在多个分区中指定,则其第一次出现的值优先。 - -状态转储文件也有一个固定的循环策略。 -目前,每个状态转储文件的容量为10MB,最多可以有10个这样的文件。 -当前正在写入的状态转储文件将始终是上面配置的值或默认的`yunikorn-state.txt`。 -当达到文件大小限制时,日志旋转器(`lumberjack`)将通过在文件前加上时间戳来修改文件,并创建一个具有相同的无前缀名称的新文件来写入状态转储。 -如果达到状态转储文件的最大数量,轮换策略将删除根据标记时间戳的最旧文件。 - -### 限制 -限制(limits)为分区或队列定义一组限制对象,以及它可以在分区或任何级别的队列上设置。 -```yaml -limits: - - limit: <描述> - - limit: <描述> -``` - -限制对象是一个复杂的配置对象,它为一组用户和/或群组定义一个限制。 -多个独立的限制可以设置为队列或分区上一个`limits`条目的一部分。 -不属于限制设置的用户和/或群组将不受限制。 - -limits条目的示例: -```yaml -limits: - - limit: <描述> - users: - - <用户名或"*"> - - <用户名> - groups: - - <群组名称或"*"> - - <群组名称> - maxapplications: <1..最大值> - maxresources: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] -``` - -队列限制的情况下,应用递归限制。 -这意味着对`root`队列的限制是集群中用户或群组的总体限制。 -因此,`root`队列限制也等同于`partition`限制。 - -limits参数: -* limit -* users -* groups -* maxapplications -* maxresources - -_limit_参数是limits条目的可选描述。 -除了使配置易于理解和可读之外,它不用于任何其他用途。 - -可以配置的_users_和_groups_可以是以下两种类型之一: -* 一个星号字符 "*" -* users或groups的列表。 - -如果users或groups的条目包含超过1个条目,则它始终被视为users或groups的列表。 -星号字符“*”为通配符,匹配所有用户或群组。 -不允许在其他列表元素旁边指定星号字符。 -列表中的重复条目将被忽略,并不会导致解析错误。 - -_maxapplications_是一个无符号整数值。 -当_maxapplications_大于1,它允许您限制为配置的用户或群组运行的应用的数量。 -不允许指定_maxapplications_为0,因为_maxapplications_为0时,隐含拒绝任何访问。 -拒绝访问的规范应交由ACL条目处理。 - -_maxresources_参数可用于指定一个或多个资源的限制。 -_maxresources_使用与队列的[resources](#资源)参数相同的语法。 -未在列表中指定的资源不受限制。 -资源限制可以设置为 0,这可以防止用户或群组请求指定的资源,即使队列或分区具有可用的特定资源也是如此。 -不允许将总体资源限制指定为零,换言之,这意味着限制中指定的至少一个资源必须大于零。 -如果资源在队列上不可用,则应使用队列定义上的最大资源。 -指定一个实际上为零的限制,_maxapplications_ 为零并且所有资源限制为零,这是不允许的,并且会导致解析错误。 - -每个用户或群组都有一个限制,它*不是*所有用户或群组的组合限制。 - -举个例子: -```yaml -limit: "example entry" -maxapplications: 10 -users: -- sue -- bob -``` -在这种情况下,用户`sue`和`bob`都被允许运行10个应用。 - -### 资源 -队列的resources条目可以为队列设置_guaranteed_和/或_maximum_资源,yunikorn会递归地检查资源限制。 -leaf队列的资源使用量是为该队列分配的所有资源的总和。 -parent队列的资源使用量是该parent队列下面所有队列,leaf和parent队列的资源使用量的总和。 - -root队列没有_guaranteed_的资源设置。 -root队列的_max_资源限制自动等于集群大小。 -如果root队列设置了任何限制,则会发生解析错误。 -leaf队列在定义时不能设置任何资源限制。 - -配置后的_max_资源对可以在任何时间点分配给队列的所有分配的大小进行了硬性限制。 -_max_资源可以设置为0,这使得资源对队列不可用。 -_guaranteed_资源用于计算队列份额和分配期间,它用作决定将分配分配给哪个队列的输入之一。 -抢占使用队列的_guaranteed_资源作为队列不能低于的基础。 - -基本的`resources` yaml条目: -```yaml -resources: - guaranteed: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] - max: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] -``` -列表中未指定的资源不受限制,对于最大(max)资源,或在保证(guaranteed)资源的情况下保证。 - -可以为资源数量指定一个可选的后缀。 -有效的国际单位制后缀是`k`、`M`、`G`、`T`、`P` 和 `E`,用于10的幂,以及`Ki`、`Mi`、`Gi`、`Ti`、 `Pi`和`Ei`表示2的幂。 -此外,`vcore`类型的资源可能带有后缀`m`以表示millicores。 例如,`500m`是vcore的50%。 -默认情况下,`memory`类型的单位以byte为单位进行解释。 -所有其他资源类型都没有指定的基本单位。 - -注意,以上单位行为从yunikorn 1.0开始有效 -以前的版本将`memory`解释为1000000(百万)bytes的单位,将`vcore`解释为millicores。 - -### 子模板 - -子模板(child template)可以在父类型队列的队列层次结构中的任何级别来定义。 -parent队列可以提供一个模板来定义它下面的动态leaf队列的行为。 -如果parent队列定义了子模板,则没有子模板的parent队列会从其parent队列继承子模板。 - -模板中支持的配置如下所示。 -1. application sort policy -2. max resources -3. guaranteed resources -4. max applications - -举个例子: -```yaml - partitions: - - name: default - placementrules: - - name: provided - create: true - queues: - - name: root - submitacl: '*' - childtemplate: - maxapplications: 10 - properties: - application.sort.policy: stateaware - resources: - guaranteed: - vcore: 1 - memory: 1G - max: - vcore: 20 - memory: 600G - queues: - - name: parent - parent: true - childtemplate: - resources: - max: - vcore: 21 - memory: 610G - - name: notemplate - parent: true -``` -在这种情况下,`root.parent.sales`将直接使用parent队列`root.parent`的子模板。 -相比之下,`root.notemplate.sales`将使用在队列`root`上设置的子模板,因为其parent队列 `root.notemplate` 从队列`root`继承了子模板。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/resource_quota_mgmt.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/resource_quota_mgmt.md deleted file mode 100644 index 3f7a42f141e..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/resource_quota_mgmt.md +++ /dev/null @@ -1,336 +0,0 @@ ---- -id: resource_quota_management -title: 资源配额管理 ---- - - - -## 配额配置和规则 -与 Kubernetes 提供的简单命名空间资源配额相比,YuniKorn 可以提供一个更细化的资源配额管理设置。 - -在 Kubernetes 上,一个 pod 在提交时必须符合命名空间的配额。 -如果 pod 不适合命名空间配额, pod 就会被拒绝。 -客户端必须实现重试机制,如果它需要该 pod 被调度,就重新提交该 pod 。 - -与 Kubernetes 中的配额相反, YuniKorn 不在提交时强制执行配额,而只对主动消耗的资源执行配额。 -解释一下区别:当使用 YuniKorn 执行配额时,提交给 Kubernetes 的新 pod 总是被接受。 - Yunikorn 将对 pod 进行排队,而不将排队的 pod 的资源计入已消耗的配额。 -当 YuniKorn 试图调度 pod 时,它会在调度时检查 pod 是否符合为 pod 所分配的队列配置的配额。 -如果这时 pod 不符合配额, pod 就会被跳过,不计入资源消耗。 -这意味着,在一个 pod 的调度尝试成功之前,一个 pod 在 YuniKorn 配额系统中不消耗资源。 - -YuniKorn 中的资源配额与队列及其在队列层次结构中的位置有关。 -队列结构的基础,即 `root` 队列,不允许设置配额,因为它反映了集群的当前规模。 -节点的增加和删除会自动更新 `root` 队列的配额。 - -除了 `root` 队列,配额可以设置,并在层次结构的任何一点上执行。 -每个队列都可以有一个配额设置。配额在整个层次结构中是递归执行的。 -这意味着子队列使用的资源不能超过父队列的**配置的**配额。 -因此,在子队列上设置大于其父队列配额的配额不会有任何影响,并被作为配置错误处理。 - -在层次结构中,还有一些需要考虑的规则。 -如果一个父队列有多个子队列,所有子队列的**使用量之和不能超过父队列的**配置配额。 -然而,从配置的角度来看,这并不意味着所有子队的**配置的**配额之和必须小于父队的配额。 - -![队列定额](./../assets/queue-resource-quotas.png) - -举个例子,`root.parent` 队列的配额是 900。 -它包含三个子队列,其中两个有配额设置。 -`root.parent.child1` 没有设置配额,因此将被限制在 `root.parent` 的配额内。 -另外两个队列 `root.parent.child2` 和 `root.parent.child3` 各设置了 750 的配额。 -在正常运行期间,3 个子队列的总使用量将是 900。 -在每个子队列中运行的应用程序,每个都有超过 1000 的需求。 - -在这种情况下,分配可能是以下任何一种: -* 所有 900 个都被 `child1` 队列使用 -* 平均分布在 3 个队列中(每个队列 300 个)。 -* `child2` 最大使用 750,剩下的 150 由 `child3` 使用。 - -队列之间的确切分布将是波动的,取决于调度策略。 - -## 转换 Kubernetes 资源和配额 - -对pod的资源支持仅限于作为_需求_规范的一部分而指定的资源: - -* _cpu_ 被映射到 _vcore_,其值为 milli cpu。 -* _memory_ 被映射到 _memory_,其值为MB(1 MB = 10^6 B = 1 000 000 B)。 -* 所有其他资源都按照规定进行映射。 - -支持 [Kubernetes文档](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) 中提到的扩展资源。 - -有一个单一容器的 pod 例子: -```yaml -apiVersion: v1 -kind: Pod -spec: - containers: - - name: container-1 - resources: - requests: - cpu: "250m" - memory: "1Gi" - hugepages-1Gi: "1" -``` -上述规范将在 YuniKorn 中为调度设置 pod 资源请求: -* _vcore_ -> 250m -* _memory_ -> 1073741824 -* _hugepages-1Gi_ -> 1 - -两个备注: -多个容器规格将被自动汇总为一个总的 pod 资源请求。所有的内存都是以字节为单位报告的。 - -在为队列使用静态队列定义的情况下,对配额中可指定的资源类型没有限制。 -作为自动队列创建的一部分,命名空间上的配额注释被限制在相当于 _cpu_ 和 _memory_ 的资源。 -参见下面的 [设置](#命名空间配额),了解命名空间上的配额注释。 - -## Kubernetes 和 YuniKorn 配额互动 -建议关闭而不是配置 Kubernetes 命名空间配额。 -只使用 YuniKorn 队列配额提供了一个更灵活的设置,并允许对工作负载进行排队。 - -在同时开启 YuniKorn 和 Kubernetes 配额的设置中,考虑以下几点: -* 需要维护两个独立的配置。 - 这增加了维护负担,以及配置错误的可能性。 -* 两个配额都会被强制执行。 - -开启这两个配额可能会导致意外的行为。 -主要问题是,Kubernetes 命名空间配额在提交时被强制执行。 -有三种配额配置的组合是可能的。 -当与 YuniKorn 配额结合使用时,这3种组合可能有两种效果。 - -1. 两种配额都是_平等的_:工作负载将不被排队,可以使用全部配置的配额。 - - 最大使用量和排队将被限制在设定的配额内 -2. Kubernetes 配额比 YuniKorn 低:YuniKorn 配额将永远不会达到,工作负载将不会被排队。 - - 最大使用量将被限制在 Kubernetes 的配额内。 -3. Kubernetes 配额比 YuniKorn 高: YuniKorn 将把使用量限制在 YuniKorn 中设置的配额。 - Kubernetes 配额将在提交时强制执行,从而为可以在 YuniKorn 配额之上排队的工作负载设置限制。 - - 最大使用量将被限制在 YuniKorn 的配额内。 - - 工作负载的排队将被限制在 Kubernetes 配额内。 - -:::note -下面的配置例子只是为了演示需要的格式 -来创建一个设置了配额的队列层次结构。 -::: - -## 静态队列定义 - -### 目标 -一个预先配置好的具有最大和保证容量的队列层次结构。 -用户只能向叶子队列提交申请。 -这种方法管理每个队列的资源容量,适用于队列不经常变化的情况。 - -### 配置 -将以下配置应用于 YuniKorn 的 configmap,以: -* 在 `root` 下设置 3 个队列 -* 每个队列都有一个特定的保证和最大容量 -* 任何人都可以向任何队列提交 - -```yaml -partitions: - - name: default - queues: - - name: root - submitacl: '*' - queues: - - name: advertisement - resources: - guaranteed: - memory: 500G - vcore: 50 - max: - memory: 800G - vcore: 80 - - name: search - resources: - guaranteed: - memory: 400G - vcore: 40 - max: - memory: 600G - vcore: 60 - - name: sandbox - resources: - guaranteed: - memory: 100G - vcore: 10 - max: - memory: 100G - vcore: 10 -``` - -### 运行一个工作负载 -为了在特定队列中运行应用程序,你需要在所有 pod 规格中设置以下标签。 -所有具有相同 `applicationID` 标签的 pod 被认为是一个应用程序。 -在下面的例子中,应用程序 `my-test-app` 将在队列 `root.sandbox` 中运行: - -```yaml -labels: - app: my-test-app - applicationId: "my-test-app-01" - queue: root.sandbox -``` - -## 名称空间到队列的映射 - -### 目标 -自动将Kubernetes的 `namespace` 映射到 YuniKorn 的队列。 -用户在 Kubernetes 中创建所需的命名空间。 -YuniKorn k8s shim 和核心调度器会自动传递所需信息,并将命名空间映射到队列中,如果队列不存在,则创建队列。 -资源配额将由 YuniKorn 管理,而不是使用 Kubernetes 命名空间配额。 -这确实需要按照下面的 [设置](#命名空间配额) 设置命名空间,不需要 Kubernetes 配额的执行和标签。 - -### 配置 -将以下配置应用于 YuniKorn 的配置图: - -```yaml -partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*' - properties: - application.sort.policy: stateaware -``` - -该配置根据 `tag` 规则放置一个应用程序。 -选择的标签是 `namespace` 标签,它由 k8s shim 自动添加到所有被创建的应用程序中。 -`create` 标志被设置为 `true`,如果队列不存在,它将触发与命名空间同名的队列的创建。 - -自动创建的子队列中的应用程序将根据父队列上设置的排序策略进行排序。 -在这种情况下,属性 `application.sort.policy` 在此配置中被设置为 `stateaware` 。 -这是一个适用于批处理作业的简单应用排序策略,你可以找到更多的文件 [这里](sorting_policies.md#stateawarepolicy)。 - -你可以在安装过程中使用 helm charts 来改变配置,通过覆盖在 -[helm chart template](https://github.com/apache/yunikorn-release/blob/master/helm-charts/yunikorn/values.yaml#L71-L81)。 - -### 命名空间配额 -Kubernetes 中的命名空间包含配额信息。 -如果在命名空间上设置了配额,Kubernetes 将自动执行该配额。 -在 YuniKorn 被用于执行配额的情况下,必须在命名空间上设置配额。 - -为了允许在命名空间上指定配额,应在命名空间对象中设置以下注释: - -```yaml -yunikorn.apache.org/namespace.quota: "{\"cpu\": \"64\", \"memory\": \"100G\", \"nvidia.com/gpu\": \"1\"}" -``` -YuniKorn 将解析这些注释,并设置映射到该命名空间的队列的最大容量。 -指定的值遵循标准的 Kubernetes 格式和单位规范。 -注释值必须是一个符合 json 的字符串。确保双引号被正确转义,以免造成任何问题。 - -上面的例子将把映射到注释命名空间的队列限制在 64 个 CPU、100GB 内存和 1 个 `nvidia.com/gpu`。 - -[已废弃] -以下注释已被废弃,并将在下一个主要版本中被删除。 -它们只支持映射内存和cpu,不支持其他资源类型。 -```yaml -yunikorn.apache.org/namespace.max.cpu: "64" -yunikorn.apache.org/namespace.max.memory: "100Gi" -``` -废弃注释的例子将把队列配额设置为 64 个 CPU 和 100GB 内存。 - -### 运行一个工作负载 - -应用程序,以及作为应用程序一部分的 pod,可以在没有特定标签的情况下提交。 -YuniKorn 将自动添加所需的标签。 -如果需要,配置的放置规则将创建队列,并将应用程序添加到队列中。 - -例如,如果一个应用程序被提交到命名空间 `development` ,那么该应用程序将在 `root.development` 队列中运行。 - -## 命名空间的父队列映射 - -### 目标 -尽管使用 `namespace` 标签的标签放置规则能够将应用程序放置在队列中,但这在所有设置中可能是不够的。 -在某些情况下,例如多租户,命名空间需要被归为一组。 -管理员可以对命名空间进行注释,如果设置了放置规则,可以根据多个注释动态放置应用程序。 -YuniKorn 不能也不会将一个命名空间的所有注解添加到一个应用程序。 - -为了帮助支持这种分组情况,可以在命名空间上标记一个父队列。 - -### 配置 -这个功能的配置由两部分组成: -1. 映射规则 -1. 命名空间注释 - -首先,我们在 YuniKorn 的 configmap 上设置以下配置: - -```yaml -partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - parent: - name: tag - value: namespace.parentqueue - queues: - - name: root - queues: - - name: production - parent: true - - name: development - parent: true -``` - -用于命名空间到队列映射的配置与 [上文](#名称空间到队列的映射) 相同。 -作为放置规则的扩展,添加了一个 `parent` 规则以支持分组。 -父级规则用于生成层次结构中的父级,或上面的队列。 -该规则使用应用程序中的标签 `namespace.parentqueue` 来生成父队列名称。 -`namespace.parentqueue` 标签由 Kubernetes shim 自动添加,但确实需要一个命名空间注释(见下文)。 - -在给出的规则配置示例中,`create` 标志没有在父规则上设置。 -这意味着父队列必须存在于配置中,否则应用提交将失败。 -对于这个例子的配置,这意味着父队的支持值被限制为 `production` 和 `development`。 - -不能使用任何这些映射在父队列上设置配额。 -根据前面提供的命名空间映射,与命名空间相关的配额设置在命名空间队列上,而不是父队。 - -父队列的配额必须总是直接在配置中设置。 -这需要在父规则上将 `create` 标志设置为 `false`。 - -### 命名空间父队列 -与命名空间名称本身相反,并与配额设置相一致,命名空间需要被注解以使用父队列映射。 -命名空间名称在 Kubernetes 中必须是唯一的,这不受此注释的影响。 -相同的注解值可以用于多个命名空间: -```yaml -yunikorn.apache.org/parentqueue: root.production -``` - -上面的例子注释将把父队列映射到现有的 `root.production` 队列。 -注意,如果需要的话,规则将完全限定名称,因此你可以省略注释中的 `root.` 部分。 -如果注释以 `root.` 开头,系统会认为这是一个完全合格的队列名称。 - -为了使图片更完整,这里有一张图片,显示了 YuniKorn 中从 Kubernetes 命名空间到队列的映射。 -它使用了 Kubernetes 中命名空间的注释,以及映射规则的配置示例。 -`finance` 和 `sales`命名空间成为队列,归入父队列 `production` 之下。 -命名空间 `dev` 和 `test` 被放在 `development` 父队列下。 - -![队列配额](./../assets/namespace-mapping.png) - -### 运行一个工作负载 -应用程序,以及作为应用程序一部分的 pod,可以在没有特定标签或更改的情况下提交。 -YuniKorn 将添加标签,安置规则将做其余的事情。 -配置的放置规则将创建队列(如果需要),并将应用程序添加到队列中。 - -由于命名空间 `finance` 被注释为示例值,并且规则已经到位。 -`finance` 命名空间的应用程序将在动态创建的 `root.production.finance` 队列中运行。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/service_config.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/service_config.md deleted file mode 100644 index 362c1af7462..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/service_config.md +++ /dev/null @@ -1,792 +0,0 @@ ---- -id: service_config -title: 服务配置 ---- - - - -YuniKorn的官方版本是通过Helm charts部署到Kubernetes中的。YuniKorn的配置分为两部分:Helm配置和YuniKorn服务配置。 - -## Helm 配置 -Helm配置是用于将YuniKorn部署到Kubernetes的选项。 - -可以在YuniKorn安装期间通过Helm进行以下设置配置,可以使用Helm的命令行方式,例如`--set key=value`,也可以使用外部文件方式:`-f file.yaml`。以下示例将以YAML语法表示。 - -### 容器镜像 -YuniKorn以一组容器镜像的形式提供。可以按照以下方式自定义其位置和拉取策略: - - # 标准调度器的镜像信息 - image: - repository: apache/yunikorn - tag: scheduler-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - - # 插件调度器的镜像信息 - pluginImage: - repository: apache/yunikorn - tag: scheduler-plugin-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - - # Web UI的镜像信息 - web: - image: - repository: apache/yunikorn - tag: web-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - - # 准入控制器的镜像信息 - admissionController: - image: - repository: apache/yunikorn - tag: admission-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - -### Kubernetes 配置 - -#### affinity -设置YuniKorn调度器Pod的亲和性。 - -默认值: `{}` - -示例: - - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: - - primary1 - - primary2 - -#### admissionController.affinity -设置YuniKorn准入控制器Pod的亲和性。 - -默认值: `{}` - -示例: - - admissionController: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: - - primary1 - - primary2 - -#### hostNetwork -控制调度器是否应在主机网络中运行。 - -默认值: `false` - -示例: - - hostNetwork: true - -#### admissionController.hostNetwork -控制准入控制器是否应在主机网络中运行。 - -默认值: `true` - -示例: - - admissionController: - hostNetwork: false - -#### imagePullSecrets -提供提取YuniKorn镜像所需的secret。 - -默认值: `[]` - -示例: - - imagePullSecrets: - - secret1 - - secret2 - -#### nodeSelector -设置用于放置YuniKorn调度器Pod的节点选择算符。 - -默认值: `{}` - -示例: - - nodeSelector: - role.node.kubernetes.io/infra: "true" - -#### admissionController.nodeSelector -设置用于放置YuniKorn准入控制器Pod的节点选择算符。 - -默认值: `{}` - -示例: - - admissionController: - nodeSelector: - role.node.kubernetes.io/infra: "true" - -#### admissionController.replicaCount -设置用于YuniKorn准入控制器的副本数。可以将其设置为大于1以实现高可用性。 - -默认值: `1` - -示例: - - admissionController: - replicaCount: 2 - -#### serviceAccount -为YuniKorn调度器设置备用服务账户。 - -不建议更改此值,因为Helm会为默认用户安装基于角色的访问控制(RBAC)策略,而这对于正确的功能是必需的。 - -默认值: `yunikorn-admin` - -示例: - - serviceAccount: my-account - -#### admissionController.serviceAccount -为YuniKorn准入控制器设置备用服务账户。 - -不建议更改此值,因为Helm会为默认用户安装基于角色的访问控制(RBAC)策略,而这对于正确的功能是必需的。 - -默认值: `yunikorn-admission-controller` - -示例: - - admissionController: - serviceAccount: my-account - -#### service.type -设置用于调度器的服务类型。 - -默认值: `ClusterIP` - -示例: - - service: - type: ClusterIP - -#### admissionController.service.type -设置用于准入控制器的服务类型。 - -默认值: `ClusterIP` - -示例: - - admissionController: - service: - type: ClusterIP - -#### service.port -设置在YuniKorn调度器服务中用于REST API的暴露端口。不建议更改此值。 - -默认值: 9080 - -示例: - - service: - port: 9080 - -#### service.portWeb -设置在YuniKorn调度器服务中用于Web UI的暴露端口。不建议更改此值。 - -默认值: 9889 - -示例: - - service: - portWeb: 9889 - -#### tolerations -设置用于YuniKorn调度器Pod的容忍规则。 - -默认值: `[]` - -示例: - - tolerations: - - key: *infraRoleKey - operator: Equal - value: "true" - effect: NoSchedule - - key: CriticalAddonsOnly - operator: Exists - -#### admissionController.tolerations -设置用于YuniKorn准入控制器Pod的容忍规则。 - -默认值: `[]` - -示例: - - admissionController: - tolerations: - - key: *infraRoleKey - operator: Equal - value: "true" - effect: NoSchedule - - key: CriticalAddonsOnly - operator: Exists - -### 资源利用率 -可以按照以下方式自定义YuniKorn Pod所需的资源: - - # 调度器容器的资源 - resources: - requests: - cpu: 200m - memory: 1Gi - limits: - cpu: 4 - memory: 2Gi - - # Web UI容器的资源 - web: - resources: - requests: - cpu: 100m - memory: 100Mi - limits: - cpu: 100m - memory: 500Mi - - # 准入控制器的资源 - admissionController: - resources: - requests: - cpu: 100m - memory: 500Mi - limits: - cpu: 500m - memory: 500mi - -### 自选功能 - -#### embedAdmissionController -控制是否启用YuniKorn准入控制器。 - -默认值: `true` - -示例: - - embedAdmissionController: false - -#### enableSchedulerPlugin -控制是否以调度器插件模式运行YuniKorn。 - -默认值: `false` - -示例: - - enableSchedulerPlugin: true - -### YuniKorn 默认值 - -#### yunikornDefaults -设置将呈现到 `yunikorn-defaults` ConfigMap的条目。这可以用于在部署时预配置YuniKorn。可以在此处设置 [YuniKorn 配置](#yunikorn-配置) 中声明的任何设置。 - -默认值: `{}` - -示例: - - yunikornDefaults: - service.clusterId: yunikorn-01 - service.policyGroup: group-01 - group-01.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - - -### 弃用设置 -以下设置已被弃用,或在将来的 YuniKorn 版本中被删除。现在应该在 `yunikorn-configs` ConfigMap 或通过 Helm 的 `yunikornDefaults` 部分指定: - -| 弃用设置 | ConfigMap 替代方案 | -| --------------------------------------- | ----------------------------------------------- | -| operatorPlugins | service.operatorPlugins | -| placeHolderImage | service.placeholderImage | -| admissionController: processNamespaces | admissionController.filtering.processNamespaces | -| admissionController: bypassNamespaces | admissionController.filtering.bypassNamespaces | -| admissionController: labelNamespaces | admissionController.filtering.labelNamespaces | -| admissionController: noLabelNamespaces | admissionController.filtering.noLabelNamespaces | -| configuration | queues.yaml | - -以下是一個過時的例子: - - operatorPlugins: general - placeHolderImage: registry.k8s.io/pause:3.7 - admissionController: - processNamespaces: "^spark-,^mpi-" - bypassNamespaces: "^kube-system$" - labelNamespaces: "^spark-" - noLabelNamespaces: "^mpi-legacy-" - configuration: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -以下是替代示例: - - yunikornDefaults: - service.policyGroup: queues - service.operatorPlugins: general - service.placeholderImage: registry.k8s.io/pause:3.7 - admissionController.processNamespaces: "^spark-,^mpi-" - admissionController.bypassNamespaces: "^kube-system$" - admissionController.labelNamespaces: "^spark-" - admissionController.noLabelNamespaces: "^mpi-legacy-" - queues.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -近期,如果同时指定了被弃用的参数和替代的ConfigMap条目,则ConfigMap条目将优先生效。 - - -## YuniKorn 配置 - -YuniKorn的服务配置由两个 Kubernetes ConfigMaps 控制,它们分别是在安装 YuniKorn 的命名空间中:`yunikorn-defaults` 和 `yunikorn-configs`。 - -运行时,YuniKorn会轮询这些ConfigMaps并将它们合并以形成有效配置。如果在两个 ConfigMaps 中都存在某个设置,则 `yunikorn-configs` 中的设置将覆盖 `yunikorn-defaults` 中的设置。 - -`yunikorn-defaults` 的目的是提供一种机制,供 Helm 配置初始的服务配置细节。它不应该被直接修改。 - -`yunikorn-configs` ConfigMap 完全不受 Helm 管理,适用于可能随时间变化的配置,如队列配置。所有对 YuniKorn 配置的更改都应在此处进行,而不是在基础设施供应之外。 - -### 默认 ConfigMap - -如果没有提供任何配置映射,或者某个选项未被指定,YuniKorn将使用此处列出的默认值: - - apiVersion: v1 - kind: ConfigMap - metadata: - name: yunikorn-configs - data: - service.clusterId: "mycluster" - service.policyGroup: "queues" - service.schedulingInterval: "1s" - service.volumeBindTimeout: "10s" - service.eventChannelCapacity: "1048576" - service.dispatchTimeout: "5m" - service.operatorPlugins: "general" - service.disableGangScheduling: "false" - service.enableConfigHotRefresh: "true" - service.placeholderImage: "registry.k8s.io/pause:3.7" - service.instanceTypeNodeLabelKey: "node.kubernetes.io/instance-type" - health.checkInterval: "30s" - log.level: "0" - kubernetes.qps: "1000" - kubernetes.burst: "1000" - admissionController.webHook.amServiceName: "yunikorn-admission-controller-service" - admissionController.webHook.schedulerServiceAddress: "yunikorn-service:9080" - admissionController.filtering.processNamespaces: "" - admissionController.filtering.bypassNamespaces: "^kube-system$" - admissionController.filtering.labelNamespaces: "" - admissionController.filtering.noLabelNamespaces: "" - admissionController.accessControl.bypassAuth: "false" - admissionController.accessControl.trustControllers: "true" - admissionController.accessControl.systemUsers: "^system:serviceaccount:kube-system:" - admissionController.accessControl.externalUsers: "" - admissionController.accessControl.externalGroups: "" - queues.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -### 服务设置 -YuniKorn可理解以下参数: - -#### service.clusterId -为正在配置的集群设置标识符。这将作为REST API调用的一部分返回。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `mycluster` - -示例: - - service.clusterId: "yunikorn-east" - -#### service.policyGroup -定义此调度器使用的策略组。策略组用于选择多个队列配置之一。此设置的值加上`.yaml`的扩展名控制用于检索分区和队列配置的ConfigMap条目。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `queues` - -示例: - - service.policyGroup: group_b - group_b.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -#### service.schedulingInterval -控制YuniKorn执行调度运行的频率。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `1s` - -示例: - - service.schedulingInterval: "5s" - -#### service.volumeBindTimeout -控制卷绑定失败的超时时间。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `10s` - -示例: - - service.volumeBindTimeout: "30s" - -#### service.eventChannelCapacity -控制YuniKorn一次允许有多少个内部调度事件在运行。作為内存不足的保护。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `1048576` - -示例: - - service.eventChannelCapacity: "1000000" - -#### service.dispatchTimeout -控制如果事件通道已满,内部事件将重新尝试调度多长时间。如果超过此超时时间,将发出警告。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `5m` - -示例: - - service.dispatchTimeout: "10m" - -#### service.operatorPlugins -控制在YuniKorn中启用的运算符插件集。目前只实现了 `general`,`spark-k8s-operator` 和 `yunikorn-app` 插件。`general` 插件不应禁用。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `general` - -示例: - - service.operatorPlugins: "general,spark-k8s-operator" - -#### service.disableGangScheduling -允许全局禁用gang调度功能(不建议)。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `false` - -示例: - - service.disableGangScheduling: "true" - -#### service.enableConfigHotRefresh -控制配置是否应该进行热重载。默认情况下,这个设置为 `true`,但是它可以被禁用,以避免 ConfigMaps 的更改被拾起直到调度器重启。 - -更改此设置将在YuniKorn不需要重启的情况下生效。 - -注意:如果禁用了此设置,则可能无法重新启用,除非重新启动YuniKorn。 - -默认值: `true` - -示例: - - service.enableConfigHotRefresh: "false" - -#### service.placeholderImage -设置将用于gang调度占位符的Pod镜像。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `registry.k8s.io/pause:3.7` - -示例: - - service.placeholderImage: "registry.k8s.io/pause:3.6" - -#### service.instanceTypeNodeLabelKey -设置节点标签的键,该键用于标识节点的实例类型。如果设置了此值,则YuniKorn将使用此标签来区分节点的实例类型。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `node.kubernetes.io/instance-type` - -示例: - - service.instanceTypeNodeLabelKey: "node.kubernetes.io/my-instance-type" - -### 健康检查设置 - -#### health.checkInterval -设置YuniKorn自动健康检查的时间间隔。 - -将该值设置为 `0` 或负值将禁用后台健康检查。 - -更改此设置不需要重新启动YuniKorn即可生效。 - -默认值: `30s` - -示例: - - health.checkInterval: "1m" - -### 日志设置 - -#### log.level -设置YuniKorn的日志详细程度。 - -更改此设置不需要重新启动YuniKorn即可生效。可用的值有: - - - `-1`: 调试(Debug) - - `0`: 信息(Info) - - `1`: 警告(Warn) - - `2`: 错误(Error) - - `3`: 不可恢復的錯誤(DPanic) - - `4`: 不可恢復的錯誤(Panic) - - `5`: 致命错误(Fatal) - -默认值: `0` (Info) - -示例: - - log.level: "-1" - -### Kubernetes 设置 - -#### kubernetes.qps -设置 YuniKorn Kubernetes 客户端每秒查询(QPS)的数量。该数字必须>=0。 - -更改此设置需要重新启动 YuniKorn 才能生效。 - -默认值: `1000` - -示例: - - kubernetes.qps: "500" - -#### kubernetes.burst -该设置用于设置 Kubernetes 查询的突发大小,临时允许事件突发到此数字,而不会超过 kubernetes.qps。 - -更改此设置需要重新启动 YuniKorn 才能生效。 - -默认值: `1000` - -示例: - - kubernetes.burst: "500" - -### 准入控制器 webhook 设置 - -#### admissionController.webHook.amServiceName -设置 YuniKorn 准入控制器所在的服务的名称下注册。这是准入控制器注册所必需的本身与 Kubernetes 兼容,通常不应更改。 - -更改此设置需要重新启动 YuniKorn 准入控制器生效。 - -默认值: `yunikorn-admission-controller-service` - -示例: - - admissionController.webHook.amServiceName: "yunikorn-admission-controller-alt-service-name" - -#### admissionController.webHook.schedulerServiceAddress -设置 YuniKorn 调度器服务的地址。这个地址必须是准入控制器可达,并由准入使用验证 ConfigMap 更改时的控制器。准入控制器将联系调度器上的 REST API 以验证任何提议 ConfigMap 更改。通常不应更改此设置。 - -更改此设置需要重新启动 YuniKorn 准入控制器生效。 - -默认值: `yunikorn-service:9080` - -示例: - - admissionController.webHook.schedulerServiceAddress: "alt-yunikorn-service:9080" - -### 准入控制器过滤设置 - -#### admissionController.filtering.processNamespaces -控制哪些命名空间会将 pod 转发给 YuniKorn 进行调度。 - -此设置是以逗号分隔的正则表达式列表。如果这个设置是一个空字符串,在所有命名空间中创建的 pod 将由 YuniKorn 调度。 - -无需重新启动准入控制器即可获取对此设置的更改。 - -默认值: empty - -示例: - - # YuniKorn 仅在 spark-* 和 mpi-* 命名空间中调度 pod - admissionController.filtering.processNamespaces: "^spark-,^mpi-" - -#### admissionController.filtering.bypassNamespaces -该设置控制哪些命名空间的 pod *不会* 被转发到 YuniKorn 进行调度。它作为 `admissionController.filtering.processNamespaces` 的例外列表。 - -此设置是一组逗号分隔的正则表达式。如果该设置为空字符串,则不会从任何命名空间中排除由 YuniKorn 处理的 pod。 - -默认情况下,该设置将排除 kube-system 命名空间中的 pod,因为这些 pod 的调度通常需要成功将节点添加到群集中。这可能会阻止 YuniKorn 本身或其他关键服务的启动。 - -更改此设置将被 admission controller 感知,无需重新启动。 - -默认值: `^kube-system$` - -示例: - - # 不要在 kube-system 或 fluentd-* 命名空间中调度 pod。 - admissionController.filtering.bypassNamespaces: "^kube-system$,^fluentd-" - -#### admissionController.filtering.labelNamespaces -该设置控制哪些命名空间的 pod 将被打上 `applicationId` 标签。默认情况下,所有由 YuniKorn 调度的 pod 都会被打上 `applicationId` 标签。 - -当使用标准部署模型运行 YuniKorn 时,所有 pod 都应打上标签,因为 YuniKorn 无法调度未定义 `applicationId` 的 pod。 - -当使用调度器插件部署模型运行 YuniKorn 时,此设置可用于过滤哪些命名空间应通过 YuniKorn 的队列模型进行调度,哪些命名空间应绕过队列模型并由嵌入式默认调度器进行调度。 - -此设置是一组逗号分隔的正则表达式。如果该设置为空字符串,则将为转发到 YuniKorn 的所有 pod 打上 `applicationId` 标签。 - -更改此设置将被 admission controller 感知,无需重新启动。 - -默认值: empty - -示例: - - # 将 applicationId 标签添加到 spark-* 命名空间中的 pod。 - admissionController.filtering.labelNamespaces: "^spark-" - -#### admissionController.filtering.noLabelNamespaces -该设置控制哪些命名空间的 pod *不会* 打上` applicationId` 标签。它作为 `admissionController.filtering.labelNamespaces` 的例外列表。 - -当使用标准部署模型运行 YuniKorn 时,所有 pod 都应打上标签,因为 YuniKorn 无法调度未定义 `applicationId` 的 pod。 - -当使用调度器插件部署模型运行 YuniKorn 时,此设置可用于过滤哪些命名空间应通过 YuniKorn 的队列模型进行调度,哪些命名空间应绕过队列模型并由嵌入式默认调度器进行调度。 - -此设置是一组逗号分隔的正则表达式。如果该设置为空字符串,则不会应用到 `admissionController.filtering.labelNamespaces` 的任何例外。 - -更改此设置将被 admission controller 感知,无需重新启动。 - -默认值: empty - -示例: - - # 在命名空间为 noqueue 时跳过队列。 - admissionController.filtering.labelNamespaces: "^noqueue$" - -### 准入控制器访问控制列表(ACL)设置 - -#### admissionController.accessControl.bypassAuth -允许外部用户创建带有用户信息的 pod。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: `false` - -示例: - - admissionController.accessControl.bypassAuth: "true" - -#### admissionController.accessControl.trustControllers -允许控制器用户创建带有用户信息的 pod。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: `true` - -示例: - - admissionController.accessControl.trustControllers: "false" - -#### admissionController.accessControl.systemUsers -逗号分隔的正则表达式列表,用于匹配允许的控制器服务账户。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: `^system:serviceaccount:kube-system:` - -示例: - - # 允许所有的 kube-system 账户以及 kube-controller-manager - admissionController.accessControl.systemUsers: "^system:serviceaccount:kube-system,^system:kube-controller-manager$" - -#### admissionController.accessControl.externalUsers -逗号分隔的正则表达式列表,用于匹配允许的外部用户。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: empty - -示例: - - # 允许 'alice'、'bob' 和 'admin-*' - admissionController.accessControl.externalUsers: "^alice$,^bob$,^admin-" - -#### admissionController.accessControl.externalGroups -逗号分隔的正则表达式列表,用于匹配允许的外部用户组。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: empty - -示例: - - # 允许 'sales'、'marketing' 和 'admin-*' - admissionController.accessControl.externalGroups: "^sales$,^marketing$,^admin-" - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/sorting_policies.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/sorting_policies.md deleted file mode 100644 index b08da46bf90..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/sorting_policies.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -id: sorting_policies -title: 排序策略 ---- - - - -调度器使用策略可以在不更改代码的情况下改变调度行为。 -可以为以下项目设置策略: -* [应用程序](#应用程序排序) -* [节点](#节点排序) -* [请求](#请求排序) - -## 应用程序排序 -通过配置为每个队列设置应用程序排序策略。排序策略设置仅对*叶子*队列有效。每个*叶子*队列可以使用不同的策略。 - -排序策略仅指定应用程序在队列内排序的顺序。 -该顺序对于指定在分配资源时首先考虑哪个应用程序非常重要。 -排序策略*不会*影响在队列中同时调度或激活的应用程序数量。 -所有具有待处理资源请求的应用程序都可以并且将在队列中调度,除非明确地被过滤掉。 -即使使用先进先出策略(FIFO)对应用程序进行排序,多个应用程序也将在队列中并行运行。 - -*父*队列始终使用公平策略对子队列进行排序。 - -考虑子队列的相对优先级(在*父*队列排序的情况下)和应用程序的相对优先级(在*叶子*队列排序的情况下)。 -要在调度时忽略应用程序和队列优先级,请将队列属性`application.sort.priority`设置为`disabled`。 - -以下配置条目将应用程序排序策略设置为FIFO,适用于队列`root.sandbox`: - -```yaml -partitions: - - name: default - queues: - - name: root - queues: - - name: sandbox - properties: - application.sort.policy: fifo -``` - -仅考虑具有未处理请求的应用程序进行调度。 -在排序应用程序*时*应用筛选器以移除所有没有未处理请求的应用程序。 - -### FifoSortPolicy -简短描述:先进先出,基于应用程序创建时间。 - -配置值:`fifo`(默认) - -在排序之前,需要过滤应用程序,并且必须有挂起(pending)的资源请求。 - -经过筛选后,应用程序将根据创建时间戳进行排序,不会使用其他过滤。 -由于系统仅在锁定状态下添加应用程序,因此不可能有两个具有完全相同时间戳的应用程序。 - -结果,最早的请求资源的应用程序获得资源。 -较晚请求的应用程序将在满足之前应用程序当前所有请求之后获得资源。 - -### FairSortPolicy -简短描述:基于资源利用率公平性排序。 - -配置值: `fair` - -在排序之前,需要过滤应用程序,并且必须有挂起(pending)的资源请求。 - -经过筛选后,剩下的应用程序将根据使用情况进行排序。 -应用程序的使用情况是指应用程序所有已确认和未确认的分配。 -计算使用情况时,将考虑应用程序中定义的所有资源。 - -达到的效果是资源相对平均分配给所有请求资源的应用程序 - -### StateAwarePolicy -简短描述:限制同一时间只有一个为 Starting 或 Accepted 状态的应用程序。 - -配置值: `stateaware` - -此排序策略需要了解应用程序状态。 -应用程序状态在[应用程序状态](developer_guide/scheduler_object_states.md#application-state)文档中进行了描述。 - -在对所有排队的应用程序进行排序之前,将应用以下过滤器: -第一个过滤器基于应用程序状态。 -以下应用程序通过过滤器并生成第一个中间列表: -* 处于 *running* 状态的所有应用程序 -* *一个*(1)处于 *starting* 状态的应用程序 -* 如果*没有*处于 *starting* 状态的应用程序,则添加 *一个*(1)处于 *accepted* 状态的应用程序 - -第二个过滤器将第一个过滤器的结果作为输入。 -再次过滤初步列表:删除所有*没有*挂起(pending)请求的应用程序。 - -根据状态和挂起(pending)请求进行过滤后,剩余的应用程序将进行排序。 -因此,最终列表将使用剩余的应用程序两次过滤并按创建时间排序。 - -回顾下 *Starting* 和 *Accepted* 状态的交互: -只有在没有处于 *Starting* 状态的应用程序时,才会添加处于 *Accepted* 状态的应用程序。 -处于 *Starting* 状态的应用程序不必有挂起(pending)请求。 -任何处于 *Starting* 状态的应用程序都将防止 *Accepted* 应用程序被添加到已过滤的列表中。 - -有关详细信息,请参阅设计文档中的 [示例](design/state_aware_scheduling.md#example-run) 运行。 - -达到的效果是,已经在运行的应用程序讲优先得到资源。 -在所有已运行的应用程序后,逐一调度新的应用程序。 - - -## 节点排序 -节点排序策略通过配置文件为每个分区设置,不同的分区可以使用不同的策略。 -以下配置项将分区`default`的节点排序策略设置为`fair`: -```yaml -partitions: - - name: default - nodesortpolicy: - type: fair -``` - -### FairnessPolicy -简要描述:按可用资源排序,按降序排列 - -配置值:`fair` (默认值) - -行为: -按可用资源的数量对节点列表进行排序,使具有最高可用资源量的节点排在列表的第一位。 -计算使用情况时,将考虑节点上定义的所有资源。 -对于节点的相同类型资源进行比较。 - -这将导致考虑可用性最低的节点首先进行新分配的分配,从而在所有可用节点上分散分配。 -这将导致每个可用节点的整体利用率降低,除非整个环境的利用率非常高。 -将所有节点的负载保持在相似水平有助于。 -在自动缩放添加新节点的环境中,这可能会触发意外的自动缩放请求。 - -### BinPackingPolicy -简要描述:按可用资源排序,按升序排列 - -配置值:`binpacking` - -行为: -按可用资源的数量对节点列表进行排序,使具有最低可用资源量的节点排在列表的第一位。 -计算使用情况时,将考虑节点上定义的所有资源。 -对于节点的相同类型资源进行比较。 - -这将导致考虑可用性最高的节点首先进行新分配的分配,从而使少量节点的利用率更高,更适合云部署。 - -## 资源加权 -节点排序策略可能使用节点利用率来确定顺序。 -因为节点可以具有多个唯一的资源类型,所以节点的利用率是由其各个资源类型的加权平均值确定的。 -资源加权可以通过使用`nodesortpolicy`的`resourceweights`部分进行自定义。 -如果`resourceweights`不存在或为空,则默认配置将`vcore`和`memory`的权重设置为相等的`1.0`。 -所有其他资源类型都将被忽略。 -只有明确提到的资源类型才会具有权重。 - -YuniKorn在内部跟踪CPU资源作为`vcore`资源类型。 -这将映射到Kubernetes资源类型`cpu`。 -除`vcore`和memory之外,所有其他资源类型在YuniKorn和Kubernetes之间具有一致的命名。 - -例如,在默认配置中,如果节点的CPU和内存分别分配了`90%`和`50%`,则该节点将被视为已使用`70%`。 - -以下配置条目为分区default设置了`vcore`权重为`4.0`和`memory`权重为`1.0`。 -这将使CPU使用的权重比内存使用高四倍: -```yaml -partitions: - - name: default - nodesortpolicy: - type: fair - resourceweights: - vcore: 4.0 - memory: 1.0 -``` - -使用此配置,在此示例中,如果节点的CPU和内存分别分配了`90%`和`50%`,则该节点将被视为已使用`82%`。 - -请注意,权重是相对于彼此的,因此指定`{4.0,1.0}`的权重等效于`{1.0,0.25}`。不允许负权重。 - -## 请求排序 -当前仅有一种策略可用于在应用程序内对请求进行排序。 -此策略不可配置。 -仅可以基于请求的优先级对请求进行排序。 -如果应用程序中有多个具有相同优先级的请求,则请求的顺序未确定。 -这意味着具有相同优先级的请求的顺序可能会在运行之间改变。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/troubleshooting.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/troubleshooting.md deleted file mode 100644 index 4b47d6b0ab4..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/troubleshooting.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -id: troubleshooting -title: 故障排除 ---- - - - -## 调度日志(Scheduler logs) - -### 检索调度日志 - -调度器会将日志写入stdout/stderr,docker容器就会将这些日志重新导向到节点的本地位置,你可以从[这里](https://docs.docker.com/config/containers/logging/configure/)读到更多的文档,这些日志可以通过[kuberctl logs](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs)检索。如: - -```shell script -//获取调度的pod -kubectl get pod -l component=yunikorn-scheduler -n yunikorn -NAME READY STATUS RESTARTS AGE -yunikorn-scheduler-766d7d6cdd-44b82 2/2 Running 0 33h - -//检索日志 -kubectl logs yunikorn-scheduler-766d7d6cdd-44b82 yunikorn-scheduler-k8s -n yunikorn -``` - -在大多数的情况下,这个命令没有办法获取所有的日志,因为调度程序的日志数量庞大,您需要设置[集群级别的日志收集](https://kubernetes.io/docs/concepts/cluster-administration/logging/#cluster-level-logging-architectures)。推荐的设置方式是利用[fluentd](https://www.fluentd.org/)在外部储存(例如s3)上持久的收集日志。 - -### 设定日志级别 - -### -:::note -我们建议通过REST API来调整日志级别,如此以来我们不需要每次修改级别时重新启动调动程序的pod。但是透过编辑部署配置来设定日志级别时,需要重新启用调度程序的pod,因此强烈不建议这么做。 -::: - -停止调度器: -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -``` - -使用vim编辑部署配置: -```shell script -kubectl edit deployment yunikorn-scheduler -n yunikorn -``` - -在容器模板的`env`字段中加入`LOG_LEVEL`。例如将`LOG_LEVEL`设置为0会将日志纪录的级别设置为`INFO`。 - -```yaml -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: -… -spec: -template: -… -spec: -containers: -- env: -- name: LOG_LEVEL -value: '0' -``` - -启用调度器: -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -可使用的日志级别: - -| 值 | 日志级别 | -|:-----: |:-------------: | -| -1 | DEBUG | -| 0 | INFO | -| 1 | WARN | -| 2 | ERROR | -| 3 | DPanic | -| 4 | Panic | -| 5 | Fatal | - -## Pods卡在`Pending`状态 - -如果Pod卡在Pending状态,则意味着调度程序找不到分配Pod的节点。造成这种情况有以下几种可能: - -### 1.没有节点满足pod的放置要求 - -可以在Pod中配置一些放置限制,例如[节点选择器(node-selector)](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)、[亲合/反亲合性(affinity/anti-affinity)](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)、对节点的[污点(taints)](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)没有一定的容忍度等。若要修正此类问题,你可以通过以下方法观察pod: - -```shell script -kubectl describe pod -n <命名空间> -``` - -pod事件中包含预测失败,而这解释了为什么节点不符合分配条件 - -### 2.队列的可用资源不足 - -如果队列的可用资源不足,Pod将等待队列资源。检查队列是否还有空间可以给Pending pod的方法有以下几种: - -1 ) 从Yunikorn UI检查队列使用情况 - -如果你不知道如何访问UI,可以参考[这里](../get_started/get_started.md#访问-web-ui)的文档。在`Queues`页面中,寻找Pod对应到的队列。你将能够看到队列中剩馀的可用资源。 - -2 ) 检查pod事件 - -运行`kubectl describe pod`以获取pod事件。如果你看到类似以下的事件:`Application does not fit into <队列路径> queue`。则代表pod无法分配,因为队列的资源用完了。 - -当队列中的其他Pod完成工作或被删除时,代表目前Pending的pod能得到分配,如果Pod依旧在有足够的剩馀资源下,保持pending状态,则可能是因为他正在等待集群扩展。 - -## 获取完整的状态 - -Yunikorn状态储存中,包含了对每个进程中每个对象的状态。透过端点来检索,我们可以有很多有用的信息,举一个故障排除的例子:分区列表、应用程序列表(包括正在运行的、已完成的以及历史应用程序的详细信息)、节点数量、节点利用率、通用集群信息、集群利用率的详细信息、容器历史纪录和队列信息。 - -状态是Yunikorn提供的用于故障排除的宝贵资源。 - -有几种方法可以获得完整的状态: -### 1.调度器URL - -步骤: -*在浏览器中打开Yunikorn UI,且在URL中编辑: -*将`/#/dashboard`取代为`/ws/v1/fullstatedump`,(例如,`http://localhost:9889/ws/v1/fullstatedump`) -*按下回车键。 - -透过这个简单的方法来观看即时且完整的状态。 - -### 2.调度器的REST API - -使用以下的调度器REST API,能够让我们看到Yunikorn的完整状态。 - -`curl -X 'GET'http://localhost:9889/ws/v1/fullstatedump-H 'accept: application/json'` - -有关储存状态的更多信息,可以参阅[检索完整状态](api/scheduler.md#retrieve-full-state-dump)的文档。 - -## 重启调度器 -:::note -最好的故障排除方法是─把「重启调度器」当作完全没有其他方法之下的最后一步,他不应该在搜集所有日志和状态之前使用。 -::: - -Yunikorn可以在重启之后恢复其状态。Yunikorn调度器的pod作为deployment部署。我们可以透过`scale`来增加和减少副本数量来重启Yunikorn调度器,方法如下: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -## 成组调度 -### 1.没有占位符被创建,且app处于pending状态 -*原因*:这通常是因为应用程序被调度气拒绝,因此没有一个pod被调度。 - -导致拒绝的常见原因有: - -1)任务群组(taskGroups)定义无效。调度程序在应用程序被提交时会进行健全性检查,以确保正确定义所有任务群组,如果这些信息的格式不正确,调度程序将拒绝该应用程序 - -2)任务群组中定义的总最小资源量大于队列的最大资源量,因此调度程序拒绝该应用程序,因为队列的资源量无法满足它。可以通过检查pod事件中的相关消息,或调度器日志来找到更多详细的错误信息。 - -*解决方案*:更正任务群组的定义并重新提交应用程序。 - -### 2.有些占位符没有被分配 -*原因*:占位符也会消耗资源,如果不能全部分配,通常是队列或者集群没有足够的资源分配给它们。在这种情况下,占位符将在一定时间后被清理,该时间由调度策略参数─`placeholderTimeoutInSeconds`所定义。 - -*解决方案*:如果占位符超时了,目前的app将会转为failed状态,无法再被调度。如果您愿意等待更长的时间,可以增加占位符超时的值。将来可能会添加倒退策略以提供重试,而不是使应用程序失败。 - -### 3.有些占位符没有被交换 -*原因*:这通常代表应用程序的pod少于任务群组中定义的最小成员数(`minMembers`) - -*解决方案*:检查任务群组字段中的`minMember`并确保其设置正确。`minMember`可以小于实际的pod数,设置大于实际pod数是无效的。 - -### 4.应用程序终止时不会清除占位符 -*原因*:所有占位符都会设置[ownerReference](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents)到应用程序的第一个真实的pod,或控制器参考。如果无法清理占位符,则意味着垃圾回收(garbage collector)的机制不正常。 - -*解决方案*:检查占位符的`ownerReference`和Kubernetes中的垃圾收集器。 - -## 仍然遇到问题? -没问题!Apache Yunikorn社区将很乐意提供帮助。您可以通过以下选项联系社区: - -1. 将您的问题发布到dev@yunikorn.apache.org。 -2. 加入[YuniKorn slack](https://join.slack.com/t/yunikornworkspace/shared_invite/enQtNzAzMjY0OTI4MjYzLTBmMDdkYTAwNDMwNTE3NWVjZWE1OTczMWE4NDI2Yzg3MmEyZjUyYTZlMDE5M2U4ZjZhNmYyNGFmYjY4ZGYyMGE)并将您的问题发布到`#yunikorn-user`频道。 -3. 加入[社区会议](http://yunikorn.apache.org/community/get_involved#community-meetings)并直接与社区成员交谈。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/usergroup_resolution.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/usergroup_resolution.md deleted file mode 100644 index 7702498cd21..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/usergroup_resolution.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -id: usergroup_resolution -title: 解析用户和群组 ---- - - - -## 用户解析 (User resolution) - -用户信息是调度周期的重要概念,他是決定「是否将作业提交到队列」的关键指标之一。Yunikorn调度器依赖k8s Shim来提供用户信息,但在Kubernetes的世界中,没有任何对象可以识别实际用户,这是基于设计使然,可以从这个[页面](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#users-in-kubernetes)中得到更多资讯。 - -在Yunikorn中有两种处理用户和群组的方法。第一种是传统的方式,使用标签`yunikorn.apache.org/usernname`。如果此标签设置在pod上,则该值会自动提取到shim中并被使用。群组解析也在shim中完成,但预设是不启用的。这种方法的问题有两个方面:首先,用户限制可以很容易地被绕过,因为提交者可以自由地将标签设置为任何值,因此这只能在受信任的环境中使用。其次,在shim中识别组别太慢了─将用户分配到多个群组​是不可行的,因为根据身份验证机制(如X509,tokens,LDP,etc)可能很难查找用户属于哪一个群组。 - -由于这些限制很大,为了向后兼容才保留了此方法,且将来可能会被删除。 - -一种更可靠和健全的机制是使用`yunikorn.apache.org/user.info`,其中用户信息中的「允许的用户或群组列表」可以由从外部设置,或者准入控制(admission controller)可以自动将其附加到每个工作负载(workflow)。 - -## 传统的用户处理 - -### 使用`yunikorn.apache.org/username`标签 - -由于kubernetes没有预定义的字段和资源能用于用户信息,且个别集群使用的用户识别工具可能有所不同,于是我们定义了标准的方法来识别用户。Yunikorn需要添加一个kubernetes[标签](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)。这里提供了[推荐的使用方法](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/),预设的标签定义如下: - -|标签|值| -|----------------------------------------------- |--------------------- | -| yunikorn.apache.org/username |用户名。可以重复该条目,但只会使用第一个值。默认的用户是`nobody` | - -举例: -```yaml -metadata: - labels: - yunikorn.apache.org/username:"john" -``` -:::tip -为了让该字段(field)成为唯一识别用户的指标,建议集群管理员使用用户识别工具,将这个标签设为不可变的字段。集群管理员或用户可以自由的使用任何方法或工具来增加这个字段和值。其中包含在提交时手动添加。 -::: - -:::note 假设 -假设: -Yunikorn假设一个应用程序的所有pod都属于同一个用户。我们建议将用户标签添加到应用程序的每个pod。这是为了确保没有任何意外。 -::: - -在[K8s的部署](https://github.com/apache/yunikorn-release/blob/master/helm-charts/yunikorn/templates/deployment.yaml)时,可以通过覆盖`USER_LABEL_KEY`来改变标签`yunikorn.apache.org/username`的默认值,这在已经添加用户标签,或出于某些安全因素下必须修改标签的情况下特别有用。 - -```yaml - env: - - name: USER_LABEL_KEY - value:"custom_user_label" -``` - -### 群组解析 (Group resolution) - -这里包含群组成员解析的定义,此外该功能是可以选择加入或移除的。群组不必是用户或群组对象所提供的一部分。当对象被加到缓存中时,群组将自动根据配置来解析。可以为每个分区(partition)设置连接到缓存的解析器(resolver)。 - -预设的群组解析器是"no resolver"。此解析器仅回传用户明和与用户同名的主要群组。 - -其他解析器: -* 操作系统解析器 -* 测试解析器 - -## 推荐的处理用户的新方式 - -从Yunikorn 1.2开始,可以使用更复杂的用户/群组解析方式。 - -在这种模式下,Yunikorn不再依赖标签`yunikorn.apache.org/username`,而是将`yunikorn.apache.org/user.info`附加到工作负载。通过简单的JSON值,定义用户名和群组: - -```yaml -metadata: - annotations: - yunikorn.apache.org/user.info:" - { - username: \"yunikorn\", - groups: [ - \"developers\", - \"devops\" - ] - }" -``` - -然而,为了加强安全性,在准入控制器中强制执行了以下操作: -* 不是集群中的每个用户都可以附加此注解(annotation),只有在配置允许时才可以使用。 -* 如果缺少注解,则准入控制器将自动添加。 -* 若尝试修改此注解将会被拒绝。 - -我们不只在pods上这样做,而是在Deployments,ReplicaSet,DeamonSet,StatefulSet,Jobs和CronJobs上都这样做。 - -此外,群组解析器不再需要放在k8s-shim中。 - -### 配置准入控制器 - -准入控制可以在`yunikorn-configs`的configmap中被配置。所有条目都以前缀`admissionController.accessControl.`开头。 - -|变量|默认值|描述| -|--|--|--| -|`bypassAuth`|false|允许任何外部用户使用用户信息集创建pod| -|`trustControllers`|true|允许Kubernetes控制器的用户创建带有用户信息集的pod| -|`systemUsers`|"^system:serviceaccount:kube-system:"|允许控制器符物帐号列表使用正则表达式| -|`externalUsers`|""|在「允许的外部用户列表」上使用正则表达式| -|`externalGroups`|""|在「允许的外部群组列表」上使用正则表达式| - -如果`bypassAuth`设置为`true`,但注解不存在且设定了已遗弃的用户标签,则准入控制器将不会把注解加到pod中。如果未设置注解也未设置用户标签,则新的注解将会被加入。 -在`bypassAuth`为`false`(默认值)的情况下,准入控制器将始终添加新的注解,而不管是否存在已弃用的标签。 - -在某些情况下,必须将用户和群组在提交时提供给Yunikorn,因为用户和群组管理由外部系统提供,查找机制并不简单。因此,在这些情况下,可以将`externalUsers`和`externalGroups`配置为正则表达式。其中,匹配的用户或群组就可以将`yunikorn.apache.org/user.info`设置为任意值。但这会影响Yunikorn内部的调度,因此必须仔细设置这些属性。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_flink.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_flink.md deleted file mode 100644 index 40eb05b1978..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_flink.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: run_flink -title: 运行Flink作业 -description: 如何与YuniKorn一起运行Flink作业 -image: https://svn.apache.org/repos/asf/flink/site/img/logo/png/100/flink_squirrel_100_color.png -keywords: - - spark ---- - - - -使用 YuniKorn 在 Kubernetes 上运行 [Apache Flink](https://flink.apache.org/) 非常容易。 -根据在 Kubernetes 上运行 Flink 的模式不同,配置会略有不同。 - -## Standalone(独立)模式 - -请关注 [Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/kubernetes.html) 以获取 standalone 部署模式的细节和示例。 -在这种模式下,我们可以直接在 Deployment/Job spec 中添加需要的标签(applicationId 和 queue)来使用 YuniKorn 调度器运行 flink 应用程序,以及 [使用 YuniKorn 调度器运行 workloads](#run-workloads-with-yunikorn-scheduler) . - -## Native(原生)模式 - -请关注 [原生 Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/native_kubernetes.html) 以获取原生部署模式的细节和示例。 -只有 Flink 1.11 或更高版本才支持在 native 模式下使用 YuniKorn 调度程序运行 Flink 应用程序,我们可以利用两个 Flink 配置 `kubernetes.jobmanager.labels` 和 `kubernetes.taskmanager.labels` 来设置所需的标签。 -例子: - -* 启动一个 Flink session -``` -./bin/kubernetes-session.sh \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dresourcemanager.taskmanager-timeout=3600000 \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox -``` - -* 启动一个 Flink application -``` -./bin/flink run-application -p 8 -t kubernetes-application \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dkubernetes.container.image= \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - local:///opt/flink/usrlib/my-flink-job.jar -``` \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_mpi.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_mpi.md deleted file mode 100644 index 374c5ca1e68..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_mpi.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: run_mpi -title: 运行MPI作业 -description: 在Yunikorn中运行MPI作业 -keywords: - - mpi ---- - - - -本指南介绍将介绍如何设置[MPI Operator](https://github.com/kubeflow/mpi-operator),以及如何使用YuniKorn调度程序运行MPIJob。 - -## 安装MPI操作器 -您可以使用以下命令安装MPI操作器。如果您在安装时遇到问题,请参阅[此文档](https://github.com/kubeflow/mpi-operator)了解详细信息。 -``` -kubectl create -f https://raw.githubusercontent.com/kubeflow/mpi-operator/master/deploy/v2beta1/mpi-operator.yaml -``` - -## 运行MPI作业 -此示例显示如何运行MPI应用程序。 - -此程序将印出一些关于workers的基础信息,然后计算圆周率的近似值。 - -这是一个计算圆周率的[YAML示例](https://github.com/apache/yunikorn-k8shim/blob/master/deployments/examples/mpioperator/Pi/pi.yaml): - -```yaml -apiVersion: kubeflow.org/v2beta1 -kind: MPIJob -metadata: - name: pi -spec: - slotsPerWorker: 1 - runPolicy: - cleanPodPolicy: Running - ttlSecondsAfterFinished: 60 - sshAuthMountPath: /home/mpiuser/.ssh - mpiReplicaSpecs: - Launcher: - replicas: 1 - template: - labels: - applicationId: "mpi_job_pi" - queue: root.mpi - spec: - schedulerName: yunikorn - containers: - - image: mpioperator/mpi-pi - name: mpi-launcher - securityContext: - runAsUser: 1000 - command: - - mpirun - args: - - -n - - "2" - - /home/mpiuser/pi - resources: - limits: - cpu: 1 - memory: 1Gi - Worker: - replicas: 2 - template: - labels: - applicationId: "mpi_job_pi" - queue: root.mpi - spec: - schedulerName: yunikorn - containers: - - image: mpioperator/mpi-pi - name: mpi-worker - securityContext: - runAsUser: 1000 - command: - - /usr/sbin/sshd - args: - - -De - - -f - - /home/mpiuser/.sshd_config - resources: - limits: - cpu: 1 - memory: 1Gi -``` -创建一个MPIJob。 -``` -kubectl create -f deployments/examples/mpioperator/Pi/pi.yaml -``` - -我们在圆周率示例中添加了Yunikorn标签,以演示如何使用yunikorn调度程序。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_nvidia.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_nvidia.md deleted file mode 100644 index 8758c1eb89e..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_nvidia.md +++ /dev/null @@ -1,347 +0,0 @@ ---- -id: run_nvidia -title: 运行NVIDIA GPU作业 -description: 如何使用Yunikorn运行通用的GPU调度示例 -keywords: - - NVIDIA GPU ---- - - - -## Yunikorn 与 NVIDIA GPUs -本指南概述了如何设置NVIDIA设备插件,该插件使用户可以在Yunikorn上运行GPU。如需更详细信息,请查看 [**使用GPU的Kubernetes**](https://docs.nvidia.com/datacenter/cloud-native/kubernetes/install-k8s.html#option-2-installing-kubernetes-using-kubeadm)。 - -### 先决条件 -在按照以下步骤之前,需要在 [**设置GPU的Kubernetes**](https://docs.nvidia.com/datacenter/cloud-native/kubernetes/install-k8s.html#install-kubernetes)上部署Yunikorn。 - -### 安装NVIDIA设备插件 -添加nvidia-device-plugin Helm存储库。 -``` -helm repo add nvdp https://nvidia.github.io/k8s-device-plugin -helm repo update -helm repo list -``` - -验证插件的最新发布版本是否可用。 -``` -helm search repo nvdp --devel -NAME CHART VERSION APP VERSION DESCRIPTION -nvdp/nvidia-device-plugin 0.12.3 0.12.3 A Helm chart for ... -``` - -部署设备插件。 -``` -kubectl create namespace nvidia -helm install --generate-name nvdp/nvidia-device-plugin --namespace nvidia --version 0.12.3 -``` - -检查Pod的状态以确保NVIDIA设备插件正在运行。 -``` -kubectl get pods -A - -NAMESPACE NAME READY STATUS RESTARTS AGE -kube-flannel kube-flannel-ds-j24fx 1/1 Running 1 (11h ago) 11h -kube-system coredns-78fcd69978-2x9l8 1/1 Running 1 (11h ago) 11h -kube-system coredns-78fcd69978-gszrw 1/1 Running 1 (11h ago) 11h -kube-system etcd-katlantyss-nzxt 1/1 Running 3 (11h ago) 11h -kube-system kube-apiserver-katlantyss-nzxt 1/1 Running 4 (11h ago) 11h -kube-system kube-controller-manager-katlantyss-nzxt 1/1 Running 3 (11h ago) 11h -kube-system kube-proxy-4wz7r 1/1 Running 1 (11h ago) 11h -kube-system kube-scheduler-katlantyss-nzxt 1/1 Running 4 (11h ago) 11h -kube-system nvidia-device-plugin-1659451060-c92sb 1/1 Running 1 (11h ago) 11h -``` - -### 测试NVIDIA设备插件 -创建一个GPU测试的YAML文件。 -``` -# gpu-pod.yaml - apiVersion: v1 - kind: Pod - metadata: - name: gpu-operator-test - spec: - restartPolicy: OnFailure - containers: - - name: cuda-vector-add - image: "nvidia/samples:vectoradd-cuda10.2" - resources: - limits: - nvidia.com/gpu: 1 -``` -部署应用程序。 -``` -kubectl apply -f gpu-pod.yaml -``` -检查日志以确保应用程序成功完成。 -``` -kubectl get pods gpu-operator-test - -NAME READY STATUS RESTARTS AGE -gpu-operator-test 0/1 Completed 0 9d -``` -检查结果。 -``` -kubectl logs gpu-operator-test - -[Vector addition of 50000 elements] -Copy input data from the host memory to the CUDA device -CUDA kernel launch with 196 blocks of 256 threads -Copy output data from the CUDA device to the host memory -Test PASSED -Done -``` - ---- -## 启用GPU时间切片( 可选 ) -GPU时间分片允许多租户共享单个GPU。 -要了解GPU时间分片的工作原理,请参阅[**在Kubernetes中使用GPU的时间切片**](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/gpu-sharing.html#introduction)。此页面介绍了使用 [**NVIDIA GPU Operator**](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/gpu-operator)启用Yunikorn中GPU调度的方法。 - - -### 配置 -以下示例说明在ConfigMap中指定多个配置。 -```yaml -# time-slicing-config.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: time-slicing-config - namespace: nvidia -data: - a100-40gb: |- - version: v1 - sharing: - timeSlicing: - resources: - - name: nvidia.com/gpu - replicas: 8 - - name: nvidia.com/mig-1g.5gb - replicas: 2 - - name: nvidia.com/mig-2g.10gb - replicas: 2 - - name: nvidia.com/mig-3g.20gb - replicas: 3 - - name: nvidia.com/mig-7g.40gb - replicas: 7 - rtx-3070: |- - version: v1 - sharing: - timeSlicing: - resources: - - name: nvidia.com/gpu - replicas: 8 -``` - -:::note -如果节点上的GPU类型不包括a100-40gb或rtx-3070,您可以根据现有的GPU类型修改YAML文件。例如,在本地Kubernetes集群中只有多个rtx-2080ti,而rtx-2080ti不支持MIG,因此无法替代a100-40gb。但rtx-2080ti支持时间切片,因此可以替代rtx-3070。 -::: - -:::info -MIG支持于2020年添加到Kubernetes中。有关其工作原理的详细信息,请参阅 [**在Kubernetes中支援MIG**](https://www.google.com/url?q=https://docs.google.com/document/d/1mdgMQ8g7WmaI_XVVRrCvHPFPOMCm5LQD5JefgAh6N8g/edit&sa=D&source=editors&ust=1655578433019961&usg=AOvVaw1F-OezvM-Svwr1lLsdQmu3) 。 -::: - -在operator命名空间nvidia,创建一个ConfigMap。 -```bash -kubectl create namespace nvidia -kubectl create -f time-slicing-config.yaml -``` - -### 安装NVIDIA GPU Operator -添加nvidia-gpu-operator Helm存储库。 -```bash -helm repo add nvidia https://helm.ngc.nvidia.com/nvidia -helm repo update -helm repo list -``` - - -使用NVIDIA GPU Operator启用共享GPU。 -- 在启用时间切片的情况下首次安装NVIDIA GPU Operator。 - ```bash - helm install gpu-operator nvidia/gpu-operator \ - -n nvidia \ - --set devicePlugin.config.name=time-slicing-config - ``` - -- 对于已安装GPU Operator的情况下,动态启用时间切片。 - ```bash - kubectl patch clusterpolicy/cluster-policy \ - -n nvidia --type merge \ - -p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config"}}}}' - ``` - -### 应用时间分片配置 -有两种方法: -- 集群范围 - -通过传递时间分片ConfigMap名称和默认配置来安装GPU Operator。 - ```bash - kubectl patch clusterpolicy/cluster-policy \ - -n nvidia --type merge \ - -p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config", "default": "rtx-3070"}}}}' - ``` - -- 在特定节点上 - -使用ConfigMap中所需的时间切片配置对节点进行标记。 - ```bash - kubectl label node nvidia.com/device-plugin.config=rtx-3070 - ``` - - -一旦安装了GPU Operator和时间切片GPU,检查Pod的状态以确保所有容器都在运行,并且验证已完成。 -```bash -kubectl get pods -n nvidia -``` - -```bash -NAME READY STATUS RESTARTS AGE -gpu-feature-discovery-qbslx 2/2 Running 0 20h -gpu-operator-7bdd8bf555-7clgv 1/1 Running 0 20h -gpu-operator-node-feature-discovery-master-59b4b67f4f-q84zn 1/1 Running 0 20h -gpu-operator-node-feature-discovery-worker-n58dv 1/1 Running 0 20h -nvidia-container-toolkit-daemonset-8gv44 1/1 Running 0 20h -nvidia-cuda-validator-tstpk 0/1 Completed 0 20h -nvidia-dcgm-exporter-pgk7v 1/1 Running 1 20h -nvidia-device-plugin-daemonset-w8hh4 2/2 Running 0 20h -nvidia-device-plugin-validator-qrpxx 0/1 Completed 0 20h -nvidia-operator-validator-htp6b 1/1 Running 0 20h -``` -验证时间分片配置是否成功应用。 -```bash -kubectl describe node -``` - -```bash -... -Capacity: - nvidia.com/gpu: 8 -... -Allocatable: - nvidia.com/gpu: 8 -... -``` - -### 测试GPU时间切片 -创建一个工作负载测试文件 plugin-test.yaml。 -```yaml -# plugin-test.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nvidia-plugin-test - labels: - app: nvidia-plugin-test -spec: - replicas: 5 - selector: - matchLabels: - app: nvidia-plugin-test - template: - metadata: - labels: - app: nvidia-plugin-test - spec: - tolerations: - - key: nvidia.com/gpu - operator: Exists - effect: NoSchedule - containers: - - name: dcgmproftester11 - image: nvidia/samples:dcgmproftester-2.1.7-cuda11.2.2-ubuntu20.04 - command: ["/bin/sh", "-c"] - args: - - while true; do /usr/bin/dcgmproftester11 --no-dcgm-validation -t 1004 -d 300; sleep 30; done - resources: - limits: - nvidia.com/gpu: 1 - securityContext: - capabilities: - add: ["SYS_ADMIN"] -``` - - -创建一个具有多个副本的部署。 -```bash -kubectl apply -f plugin-test.yaml -``` - -验证所有五个副本是否正在运行。 - -- 在Pod群中 - ```bash - kubectl get pods - ``` - - ```bash - NAME READY STATUS RESTARTS AGE - nvidia-plugin-test-677775d6c5-bpsvn 1/1 Running 0 8m8s - nvidia-plugin-test-677775d6c5-m95zm 1/1 Running 0 8m8s - nvidia-plugin-test-677775d6c5-9kgzg 1/1 Running 0 8m8s - nvidia-plugin-test-677775d6c5-lrl2c 1/1 Running 0 8m8s - nvidia-plugin-test-677775d6c5-9r2pz 1/1 Running 0 8m8s - ``` -- 在节点中 - ```bash - kubectl describe node - ``` - - ```bash - ... - Allocated resources: - (Total limits may be over 100 percent, i.e., overcommitted.) - Resource Requests Limits - -------- -------- ------ - ... - nvidia.com/gpu 5 5 - ... - ``` -- 在NVIDIA系统管理界面中 - ```bash - nvidia-smi - ``` - - ```bash - +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 520.61.05 Driver Version: 520.61.05 CUDA Version: 11.8 | - |-------------------------------+----------------------+----------------------+ - | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | - | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | - | | | MIG M. | - |===============================+======================+======================| - | 0 NVIDIA GeForce ... On | 00000000:01:00.0 On | N/A | - | 46% 86C P2 214W / 220W | 4297MiB / 8192MiB | 100% Default | - | | | N/A | - +-------------------------------+----------------------+----------------------+ - - +-----------------------------------------------------------------------------+ - | Processes: | - | GPU GI CI PID Type Process name GPU Memory | - | ID ID Usage | - |=============================================================================| - | 0 N/A N/A 1776886 C /usr/bin/dcgmproftester11 764MiB | - | 0 N/A N/A 1776921 C /usr/bin/dcgmproftester11 764MiB | - | 0 N/A N/A 1776937 C /usr/bin/dcgmproftester11 764MiB | - | 0 N/A N/A 1777068 C /usr/bin/dcgmproftester11 764MiB | - | 0 N/A N/A 1777079 C /usr/bin/dcgmproftester11 764MiB | - +-----------------------------------------------------------------------------+ - ``` - -- 在Yunikorn用户界面中的应用程序中。 -![](../../assets/yunikorn-gpu-time-slicing.png) \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_spark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_spark.md deleted file mode 100644 index 45791a18427..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/run_spark.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: run_spark -title: 运行Spark作业 -description: 如何使用YuniKorn运行Spark作业 -keywords: - - spark ---- - - - -:::note 注意 -本文档假设您已安装YuniKorn及其准入控制器。请参阅 [开始](../../get_started/get_started.md) 查看如何操作。 -::: - -## 为Spark准备docker镜像 - -要在Kubernetes上运行Spark,您需要Spark的docker镜像。您可以 -1)使用Spark团队提供的docker镜像 -2)从头开始构建一个镜像。如果你想建立自己的Spark的docker镜像,您可以找到 [完整说明](https://spark.apache.org/docs/latest/building-spark.html) -在 Spark 文档中。简化步骤: -* 下载一个支持Kubernetes的Spark版本,URL: https://github.com/apache/spark -* 构建支持Kubernetes的Spark版本: -```shell script -./buid/mvn -Pkubernetes -DskipTests clean package -``` -建议使用[dockerhub](https://hub.docker.com/r/apache/spark/tags)中不同spark版本的官方镜像 - -## 为Spark作业创建一个命名空间 - -创建一个命名空间: - -```shell script -cat < - -本章节概述了如何设置 [training-operator](https://github.com/kubeflow/training-operator) 以及如何使用 YuniKorn 调度器运行 Tensorflow 作业。 -training-operator 是由 Kubeflow 维护的一体化集成的训练 operator。它不仅支持 TensorFlow,还支持 PyTorch、XGboots 等。 - -## 安装 training-operator -您可以使用以下命令在 kubeflow 命名空间中默认安装 training operator。如果安装有问题, -请参阅 [此文档](https://github.com/kubeflow/training-operator#installation) 来查找相关的详细信息。 -``` -kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone?ref=v1.3.0" -``` - -## 准备 docker 镜像 -在开始于 Kubernetes 上运行 TensorFlow 作业之前,您需要构建 docker 镜像。 -1. 从 [deployment/examples/tfjob](https://github.com/apache/yunikorn-k8shim/tree/master/deployments/examples/tfjob) 上下载文件 -2. 使用以下命令构建这个 docker 镜像 - -``` -docker build -f Dockerfile -t kubeflow/tf-dist-mnist-test:1.0 . -``` - -## 运行一个 TensorFlow 作业 -以下是一个使用 MNIST [样例](https://github.com/apache/yunikorn-k8shim/blob/master/deployments/examples/tfjob/tf-job-mnist.yaml) 的 TFJob yaml. - -```yaml -apiVersion: kubeflow.org/v1 -kind: TFJob -metadata: - name: dist-mnist-for-e2e-test - namespace: kubeflow -spec: - tfReplicaSpecs: - PS: - replicas: 2 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 - Worker: - replicas: 4 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 -``` -创建 TFJob -``` -kubectl create -f deployments/examples/tfjob/tf-job-mnist.yaml -``` - -您可以从 YuniKorn UI 中查看作业信息。 如果您不知道如何访问 YuniKorn UI, -请阅读此 [文档](../../get_started/get_started.md#访问-web-ui)。 - -![tf-job-on-ui](../../assets/tf-job-on-ui.png) - -## 使用GPU Time-slicing -### 前提 -要使用 Time-slicing GPU,您需要先设定丛集以让GPU和Time-slicing GPU能被使用。 -- 节点上必须连接GPU -- Kubernetes版本为1.24 -- 丛集中需要安装 GPU drivers -- 透过 [GPU Operator](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/getting-started.html) 自动化的建置与管理节点中的 NVIDIA 软体组件 -- 在Kubernetes中设定 [Time-Slicing GPUs in Kubernetes](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/gpu-sharing.html) - - -在安装完 GPU Operator 及 Time-slicing GPU 以后,确认pods的状态以确保所有的containers正在运行或完成: -```shell script -kubectl get pod -n gpu-operator -``` -```shell script -NAME READY STATUS RESTARTS AGE -gpu-feature-discovery-fd5x4 2/2 Running 0 5d2h -gpu-operator-569d9c8cb-kbn7s 1/1 Running 14 (39h ago) 5d2h -gpu-operator-node-feature-discovery-master-84c7c7c6cf-f4sxz 1/1 Running 0 5d2h -gpu-operator-node-feature-discovery-worker-p5plv 1/1 Running 8 (39h ago) 5d2h -nvidia-container-toolkit-daemonset-zq766 1/1 Running 0 5d2h -nvidia-cuda-validator-5tldf 0/1 Completed 0 5d2h -nvidia-dcgm-exporter-95vm8 1/1 Running 0 5d2h -nvidia-device-plugin-daemonset-7nzvf 2/2 Running 0 5d2h -nvidia-device-plugin-validator-gj7nn 0/1 Completed 0 5d2h -nvidia-operator-validator-nz84d 1/1 Running 0 5d2h -``` -确认时间片设定是否被成功的使用: -```shell script -kubectl describe node -``` - -```shell script -Capacity: - nvidia.com/gpu: 16 -... -Allocatable: - nvidia.com/gpu: 16 -... -``` -### 使用GPU测试TensorFlow job -在这个段落中会在 Time-slicing GPU 的支援下,测试及验证TFJob的运行 - -1. 新建一个workload的测试档案tf-gpu.yaml: - ```shell script - vim tf-gpu.yaml - ``` - ```yaml - apiVersion: "kubeflow.org/v1" - kind: "TFJob" - metadata: - name: "tf-smoke-gpu" - namespace: kubeflow - spec: - tfReplicaSpecs: - PS: - replicas: 1 - template: - metadata: - creationTimestamp: - labels: - applicationId: "tf_job_20200521_001" - spec: - schedulerName: yunikorn - containers: - - args: - - python - - tf_cnn_benchmarks.py - - --batch_size=32 - - --model=resnet50 - - --variable_update=parameter_server - - --flush_stdout=true - - --num_gpus=1 - - --local_parameter_device=cpu - - --device=cpu - - --data_format=NHWC - image: docker.io/kubeflow/tf-benchmarks-cpu:v20171202-bdab599-dirty-284af3 - name: tensorflow - ports: - - containerPort: 2222 - name: tfjob-port - workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks - restartPolicy: OnFailure - Worker: - replicas: 1 - template: - metadata: - creationTimestamp: null - labels: - applicationId: "tf_job_20200521_001" - spec: - schedulerName: yunikorn - containers: - - args: - - python - - tf_cnn_benchmarks.py - - --batch_size=32 - - --model=resnet50 - - --variable_update=parameter_server - - --flush_stdout=true - - --num_gpus=1 - - --local_parameter_device=cpu - - --device=gpu - - --data_format=NHWC - image: docker.io/kubeflow/tf-benchmarks-gpu:v20171202-bdab599-dirty-284af3 - name: tensorflow - ports: - - containerPort: 2222 - name: tfjob-port - resources: - limits: - nvidia.com/gpu: 2 - workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks - restartPolicy: OnFailure - ``` -2. 创建TFJob - ```shell script - kubectl apply -f tf-gpu.yaml - ``` -3. 在Yunikorn中验证TFJob是否运行 - ![tf-job-gpu-on-ui](../../assets/tf-job-gpu-on-ui.png) - 察看pod的日志: - ```shell script - kubectl logs logs po/tf-smoke-gpu-worker-0 -n kubeflow - ``` - ``` - ....... - ..Found device 0 with properties: - ..name: NVIDIA GeForce RTX 3080 major: 8 minor: 6 memoryClockRate(GHz): 1.71 - - ....... - ..Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: NVIDIA GeForce RTX 3080, pci bus id: 0000:01:00.0, compute capability: 8.6) - ....... - ``` - ![tf-job-gpu-on-logs](../../assets/tf-job-gpu-on-logs.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/workload_overview.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/workload_overview.md deleted file mode 100644 index c7b46a4c378..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/user_guide/workloads/workload_overview.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: workload_overview -title: 概述 ---- - - - -YuniKorn调度器支持任何的Kubernetes工作负载。所需要的只是确保将Pod规范的 -`schedulerName`字段设置为`yunikorn`并将`applicationId`标签设置为每个应用程序的唯一值: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - labels: - app: sleep - applicationId: "application-sleep-0001" - name: sleep-app-1 -spec: - schedulerName: yunikorn - containers: - - name: sleep-30s - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "100M" -``` - -此外,如果存在YuniKorn准入控制器,则可以省略“schedulerName”字段,因为它将在新创建的pod上自动设置。 - -## 进阶例子 - -可以在此处找到更进阶的例子: - -* [运行Spark作业](run_spark) -* [运行Flink作业](run_flink) -* [运行TensorFlow作业](run_tf) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/assets b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/assets deleted file mode 120000 index 511ac9c0eb8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/assets +++ /dev/null @@ -1 +0,0 @@ -../../../../versioned_docs/version-0.12.1/assets \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/get_started/core_features.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/get_started/core_features.md deleted file mode 100644 index d6d3c497992..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/get_started/core_features.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: core_features -title: 特征 -keywords: - - 特征 ---- - - - -YuniKorn的主要特点包括: - -## 应用感知调度 - -YuniKorn的关键特性之一就是支持应用感知。在默认的K8s调度程序中,它只能根据Pod进行调度,而不能基于用户、作业或者队列进行更细粒度的调度。 -与之不同的是,YuniKorn可以识别用户、作业或者队列,并在做出调度决策时,考虑更多与它们相关的因素,如资源、排序等。 -这使我们能够对资源配额、资源公平性和优先级进行细粒度控制,这是多租户计算系统最重要的需求。 - -## 层次资源队列 - -层次队列提供了一种有效的机制来管理集群资源。 -队列的层次结构可以在逻辑上映射到组织结构。这为不同租户提供了对资源的细粒度控制。 -YuniKorn UI 提供了一个集中的视图来监视资源队列的使用情况,它可以帮助您了解不同租户是如何使用资源的。 -此外,用户可以利用设置最小/最大队列容量来为每个租户设定其弹性资源配额。 - -## 作业排序和排队 - -YuniKorn将每个资源队列中的队列进行排队,排序策略决定哪个应用程序可以首先获得资源。 -这个策略可以是多种多样的,例如简单的 `FIFO`、`Fair`、`StateAware` 或基于 `Priority` 的策略。 -队列可以维持应用的顺序,调度器根据不同的策略为作业分配相应的资源。这种行为更容易被理解和控制。 - -此外,当配置队列最大容量时,作业和任务可以在资源队列中正确排队。 -如果剩余的容量不够,它们可以排队等待,直到释放一些资源。这就简化了客户端操作。 -而在默认调度程序中,资源由命名空间资源配额限制:如果命名空间没有足够的配额,Pod就不能被创建。这是由配额许可控制器强制执行的。 -客户端需要更复杂的逻辑来处理此类场景,例如按条件重试。 - -## 资源公平性 - -在多租户环境中,许多用户共享集群资源。 -为了避免租户争夺资源或者可能的资源不足,需要做到更细粒度的公平性需求,以此来实现跨用户以及跨团队/组织的公平性。 -考虑到权重或优先级,一些更重要的应用可以获得超过其配额的更多的需求资源。 -这往往与资源预算有关,更细粒度的公平模式可以进一步提高资源控制。 - -## 资源预留 - -YuniKorn会自动为未完成的请求进行资源预留。 -如果Pod无法分配,YuniKorn将尝试把它预留在一个满足条件的节点上,并在这个节点上暂时分配该 pod(在尝试其他节点之前)。 -这种机制可以避免这个 Pod 需要的资源被后来提交的更小的、更不挑剔的 Pod 所挤占。 -此功能在批处理工作负载场景中非常重要,因为当对集群提交大量异构 Pod 时,很有可能一些 Pod 会处于“饥饿”状态,即使它们提交得更早。 - -## 吞吐量 - -吞吐量是衡量调度器性能的关键标准。这对于一个大规模的分布式系统来说是至关重要的。 -如果吞吐量不好,应用程序可能会浪费时间等待调度,并进一步影响服务的 SLA(服务级别协议)。 -集群越大,对吞吐量的要求也越高。[基于Kube标记的运行评估](performance/evaluate_perf_function_with_kubemark.md) 章节显示了一些性能数据。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/get_started/get_started.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/get_started/get_started.md deleted file mode 100644 index 035d25def38..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/get_started/get_started.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -id: user_guide -title: 开始 -slug: / ---- - - - -在阅读本指南之前,我们假设您有一个Kubernetes集群或本地 Kubernetes 开发环境,例如 MiniKube。 -还假定 `kubectl` 在您的环境路径内,并且配置正确。 -遵循此 [指南](developer_guide/env_setup.md) 来讲述如何使用 docker-desktop 设置本地Kubernetes集群。 - -## 安装 - -最简单的方法是使用我们的 Helm Chart 在现有的Kubernetes集群上部署YuniKorn。 -我们建议使用 Helm 3 或更高版本。 - -```shell script -helm repo add yunikorn https://apache.github.io/incubator-yunikorn-release -helm repo update -kubectl create namespace yunikorn -helm install yunikorn yunikorn/yunikorn --namespace yunikorn -``` - -默认情况下,Helm Chart 将在集群中安装调度器、web服务器和 admission-controller。 -`admission-controller` 一旦安装,它将把所有集群流量路由到YuniKorn。 -这意味着资源调度会委托给YuniKorn。在Helm安装过程中,可以通过将 `embedAdmissionController` 标志设置为false来禁用它。 - -如果你不想使用 Helm Chart,您可以找到我们的细节教程 [点击这里](developer_guide/deployment.md) 。 - -## 卸载 - -运行如下的命令卸载 YuniKorn: - -```shell script -helm uninstall yunikorn --namespace yunikorn -``` - -## 访问 Web UI - -当部署调度程序时,Web UI 也会部署在容器中。 -我们可以通过以下方式在标准端口上打开 Web 界面的端口转发: - -```shell script -kubectl port-forward svc/yunikorn-service 9889:9889 -n yunikorn -``` - -`9889` 是 Web UI 的默认端口。 -完成此操作后,web UI将在以下地址可用: http://localhost:9889 。 - -![UI 截图](./../assets/yk-ui-screenshots.gif) - -YuniKorn UI 提供了集群资源容量、利用率和所有应用信息的集中视图。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/performance/metrics.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/performance/metrics.md deleted file mode 100644 index 9dedbec73b8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/performance/metrics.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: metrics -title: Scheduler Metrics -keywords: - - metrics ---- - - - -YuniKorn leverages [Prometheus](https://prometheus.io/) to record metrics. The metrics system keeps tracking of -scheduler's critical execution paths, to reveal potential performance bottlenecks. Currently, there are three categories -for these metrics: - -- scheduler: generic metrics of the scheduler, such as allocation latency, num of apps etc. -- queue: each queue has its own metrics sub-system, tracking queue status. -- event: record various changes of events in YuniKorn. - -all metrics are declared in `yunikorn` namespace. -### Scheduler Metrics - -| Metrics Name | Metrics Type | Description | -| --------------------- | ------------ | ------------ | -| containerAllocation | Counter | Total number of attempts to allocate containers. State of the attempt includes `allocated`, `rejected`, `error`, `released`. Increase only. | -| applicationSubmission | Counter | Total number of application submissions. State of the attempt includes `accepted` and `rejected`. Increase only. | -| applicationStatus | Gauge | Total number of application status. State of the application includes `running` and `completed`. | -| totalNodeActive | Gauge | Total number of active nodes. | -| totalNodeFailed | Gauge | Total number of failed nodes. | -| nodeResourceUsage | Gauge | Total resource usage of node, by resource name. | -| schedulingLatency | Histogram | Latency of the main scheduling routine, in seconds. | -| nodeSortingLatency | Histogram | Latency of all nodes sorting, in seconds. | -| appSortingLatency | Histogram | Latency of all applications sorting, in seconds. | -| queueSortingLatency | Histogram | Latency of all queues sorting, in seconds. | -| tryNodeLatency | Histogram | Latency of node condition checks for container allocations, such as placement constraints, in seconds, in seconds. | - -### Queue Metrics - -| Metrics Name | Metrics Type | Description | -| ------------------------- | ------------- | ----------- | -| appMetrics | Counter | Application Metrics, record the total number of applications. State of the application includes `accepted`,`rejected` and `Completed`. | -| usedResourceMetrics | Gauge | Queue used resource. | -| pendingResourceMetrics | Gauge | Queue pending resource. | -| availableResourceMetrics | Gauge | Used resource metrics related to queues etc. | - -### Event Metrics - -| Metrics Name | Metrics Type | Description | -| ------------------------ | ------------ | ----------- | -| totalEventsCreated | Gauge | Total events created. | -| totalEventsChanneled | Gauge | Total events channeled. | -| totalEventsNotChanneled | Gauge | Total events not channeled. | -| totalEventsProcessed | Gauge | Total events processed. | -| totalEventsStored | Gauge | Total events stored. | -| totalEventsNotStored | Gauge | Total events not stored. | -| totalEventsCollected | Gauge | Total events collected. | - -## Access Metrics - -YuniKorn metrics are collected through Prometheus client library, and exposed via scheduler restful service. -Once started, they can be accessed via endpoint http://localhost:9080/ws/v1/metrics. - -## Aggregate Metrics to Prometheus - -It's simple to setup a Prometheus server to grab YuniKorn metrics periodically. Follow these steps: - -- Setup Prometheus (read more from [Prometheus docs](https://prometheus.io/docs/prometheus/latest/installation/)) - -- Configure Prometheus rules: a sample configuration - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] -``` - -- start Prometheus - -```shell script -docker pull prom/prometheus:latest -docker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus -``` - -Use `docker.for.mac.host.internal` instead of `localhost` if you are running Prometheus in a local docker container -on Mac OS. Once started, open Prometheus web UI: http://localhost:9090/graph. You'll see all available metrics from -YuniKorn scheduler. - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/performance/performance_tutorial.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/performance/performance_tutorial.md deleted file mode 100644 index 7d10def46c5..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/performance/performance_tutorial.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -id: performance_tutorial -title: Benchmarking Tutorial -keywords: - - performance - - tutorial ---- - - - -## Overview - -The YuniKorn community continues to optimize the performance of the scheduler, ensuring that YuniKorn satisfies the performance requirements of large-scale batch workloads. Thus, the community has built some useful tools for performance benchmarking that can be reused across releases. This document introduces all these tools and steps to run them. - -## Hardware - -Be aware that performance result is highly variable depending on the underlying hardware. All results published in the doc can only be used as references. We encourage each individual to run similar tests on their own environments in order to get a result based on your own hardware. This doc is just for demonstration purpose. - -A list of servers being used in this test are (Huge thanks to [National Taichung University of Education](http://www.ntcu.edu.tw/newweb/index.htm), [Kuan-Chou Lai](http://www.ntcu.edu.tw/kclai/) for providing these servers for running tests): - -| Manchine Type | CPU | Memory | Download/upload(Mbps) | -| --------------------- | --- | ------ | --------------------- | -| HP | 16 | 36G | 525.74/509.86 | -| HP | 16 | 30G | 564.84/461.82 | -| HP | 16 | 30G | 431.06/511.69 | -| HP | 24 | 32G | 577.31/576.21 | -| IBM blade H22 | 16 | 38G | 432.11/4.15 | -| IBM blade H22 | 16 | 36G | 714.84/4.14 | -| IBM blade H22 | 16 | 42G | 458.38/4.13 | -| IBM blade H22 | 16 | 42G | 445.42/4.13 | -| IBM blade H22 | 16 | 32G | 400.59/4.13 | -| IBM blade H22 | 16 | 12G | 499.87/4.13 | -| IBM blade H23 | 8 | 32G | 468.51/4.14 | -| WS660T | 8 | 16G | 87.73/86.30 | -| ASUSPRO D640MB_M640SA | 4 | 8G | 92.43/93.77 | -| PRO E500 G6_WS720T | 16 | 8G | 90/87.18 | -| WS E500 G6_WS720T | 8 | 40G | 92.61/89.78 | -| E500 G5 | 8 | 8G | 91.34/85.84 | -| WS E500 G5_WS690T | 12 | 16G | 92.2/93.76 | -| WS E500 G5_WS690T | 8 | 32G | 91/89.41 | -| WS E900 G4_SW980T | 80 | 512G | 89.24/87.97 | - -The following steps are needed for each server, otherwise the large scale testing may fail due to the limited number of users/processes/open-files. - -### 1. Set /etc/sysctl.conf -``` -kernel.pid_max=400000 -fs.inotify.max_user_instances=50000 -fs.inotify.max_user_watches=52094 -``` -### 2. Set /etc/security/limits.conf - -``` -* soft nproc 4000000 -* hard nproc 4000000 -root soft nproc 4000000 -root hard nproc 4000000 -* soft nofile 50000 -* hard nofile 50000 -root soft nofile 50000 -root hard nofile 50000 -``` ---- - -## Deploy workflow - -Before going into the details, here are the general steps used in our tests: - -- [Step 1](#Kubernetes): Properly configure Kubernetes API server and controller manager, then add worker nodes. -- [Step 2](#Setup-Kubemark): Deploy hollow pods,which will simulate worker nodes, name hollow nodes. After all hollow nodes in ready status, we need to cordon all native nodes, which are physical presence in the cluster, not the simulated nodes, to avoid we allocated test workload pod to native nodes. -- [Step 3](#Deploy-YuniKorn): Deploy YuniKorn using the Helm chart on the master node, and scale down the Deployment to 0 replica, and [modify the port](#Setup-Prometheus) in `prometheus.yml` to match the port of the service. -- [Step 4](#Run-tests): Deploy 50k Nginx pods for testing, and the API server will create them. But since the YuniKorn scheduler Deployment has been scaled down to 0 replica, all Nginx pods will be stuck in pending. -- [Step 5](../user_guide/trouble_shooting.md#restart-the-scheduler): Scale up The YuniKorn Deployment back to 1 replica, and cordon the master node to avoid YuniKorn allocating Nginx pods there. In this step, YuniKorn will start collecting the metrics. -- [Step 6](#Collect-and-Observe-YuniKorn-metrics): Observe the metrics exposed in Prometheus UI. ---- - -## Setup Kubemark - -[Kubemark](https://github.com/kubernetes/kubernetes/tree/master/test/kubemark) is a performance testing tool which allows users to run experiments on simulated clusters. The primary use case is the scalability testing. The basic idea is to run tens or hundreds of fake kubelet nodes on one physical node in order to simulate large scale clusters. In our tests, we leverage Kubemark to simulate up to a 4K-node cluster on less than 20 physical nodes. - -### 1. Build image - -##### Clone kubernetes repo, and build kubemark binary file - -``` -git clone https://github.com/kubernetes/kubernetes.git -``` -``` -cd kubernetes -``` -``` -KUBE_BUILD_PLATFORMS=linux/amd64 make kubemark GOFLAGS=-v GOGCFLAGS="-N -l" -``` - -##### Copy kubemark binary file to the image folder and build kubemark docker image - -``` -cp _output/bin/kubemark cluster/images/kubemark -``` -``` -IMAGE_TAG=v1.XX.X make build -``` -After this step, you can get the kubemark image which can simulate cluster node. You can upload it to Docker-Hub or just deploy it locally. - -### 2. Install Kubermark - -##### Create kubemark namespace - -``` -kubectl create ns kubemark -``` - -##### Create configmap - -``` -kubectl create configmap node-configmap -n kubemark --from-literal=content.type="test-cluster" -``` - -##### Create secret - -``` -kubectl create secret generic kubeconfig --type=Opaque --namespace=kubemark --from-file=kubelet.kubeconfig={kubeconfig_file_path} --from-file=kubeproxy.kubeconfig={kubeconfig_file_path} -``` -### 3. Label node - -We need to label all native nodes, otherwise the scheduler might allocate hollow pods to other simulated hollow nodes. We can leverage Node selector in yaml to allocate hollow pods to native nodes. - -``` -kubectl label node {node name} tag=tagName -``` - -### 4. Deploy Kubemark - -The hollow-node.yaml is down below, there are some parameters we can configure. - -``` -apiVersion: v1 -kind: ReplicationController -metadata: - name: hollow-node - namespace: kubemark -spec: - replicas: 2000 # the node number you want to simulate - selector: - name: hollow-node - template: - metadata: - labels: - name: hollow-node - spec: - nodeSelector: # leverage label to allocate to native node - tag: tagName - initContainers: - - name: init-inotify-limit - image: docker.io/busybox:latest - imagePullPolicy: IfNotPresent - command: ['sysctl', '-w', 'fs.inotify.max_user_instances=200'] # set as same as max_user_instance in actual node - securityContext: - privileged: true - volumes: - - name: kubeconfig-volume - secret: - secretName: kubeconfig - - name: logs-volume - hostPath: - path: /var/log - containers: - - name: hollow-kubelet - image: 0yukali0/kubemark:1.20.10 # the kubemark image you build - imagePullPolicy: IfNotPresent - ports: - - containerPort: 4194 - - containerPort: 10250 - - containerPort: 10255 - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=kubelet - - --name=$(NODE_NAME) - - --kubeconfig=/kubeconfig/kubelet.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: - requests: # the resource of hollow pod, can modify it. - cpu: 20m - memory: 50M - securityContext: - privileged: true - - name: hollow-proxy - image: 0yukali0/kubemark:1.20.10 # the kubemark image you build - imagePullPolicy: IfNotPresent - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=proxy - - --name=$(NODE_NAME) - - --use-real-proxier=false - - --kubeconfig=/kubeconfig/kubeproxy.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: # the resource of hollow pod, can modify it. - requests: - cpu: 20m - memory: 50M - tolerations: - - effect: NoExecute - key: node.kubernetes.io/unreachable - operator: Exists - - effect: NoExecute - key: node.kubernetes.io/not-ready - operator: Exists -``` - -once done editing, apply it to the cluster: - -``` -kubectl apply -f hollow-node.yaml -``` - ---- - -## Deploy YuniKorn - -#### Install YuniKorn with helm - -We can install YuniKorn with Helm, please refer to this [doc](https://yunikorn.apache.org/docs/#install). -We need to tune some parameters based on the default configuration. We recommend to clone the [release repo](https://github.com/apache/incubator-yunikorn-release) and modify the parameters in `value.yaml`. - -``` -git clone https://github.com/apache/incubator-yunikorn-release.git -cd helm-charts/yunikorn -``` - -#### Configuration - -The modifications in the `value.yaml` are: - -- increased memory/cpu resources for the scheduler pod -- disabled the admission controller -- set the app sorting policy to FAIR - -please see the changes below: - -``` -resources: - requests: - cpu: 14 - memory: 16Gi - limits: - cpu: 14 - memory: 16Gi -``` -``` -embedAdmissionController: false -``` -``` -configuration: | - partitions: - - - name: default - queues: - - name: root - submitacl: '*' - queues: - - - name: sandbox - properties: - application.sort.policy: fair -``` - -#### Install YuniKorn with local release repo - -``` -Helm install yunikorn . --namespace yunikorn -``` - ---- - -## Setup Prometheus - -YuniKorn exposes its scheduling metrics via Prometheus. Thus, we need to set up a Prometheus server to collect these metrics. - -### 1. Download Prometheus release - -``` -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` -``` -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. Configure prometheus.yml - -``` -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] - # 9080 is internal port, need port forward or modify 9080 to service's port -``` - -### 3. Launch Prometheus -``` -./prometheus --config.file=prometheus.yml -``` - ---- -## Run tests - -Once the environment is setup, you are good to run workloads and collect results. YuniKorn community has some useful tools to run workloads and collect metrics, more details will be published here. - ---- - -## Collect and Observe YuniKorn metrics - -After Prometheus is launched, YuniKorn metrics can be easily collected. Here is the [docs](./metrics.md) of YuniKorn metrics. YuniKorn tracks some key scheduling metrics which measure the latency of some critical scheduling paths. These metrics include: - - - **scheduling_latency_seconds:** Latency of the main scheduling routine, in seconds. - - **app_sorting_latency_seconds**: Latency of all applications sorting, in seconds. - - **node_sorting_latency_seconds**: Latency of all nodes sorting, in seconds. - - **queue_sorting_latency_seconds**: Latency of all queues sorting, in seconds. - - **container_allocation_attempt_total**: Total number of attempts to allocate containers. State of the attempt includes `allocated`, `rejected`, `error`, `released`. Increase only. - -you can select and generate graph on Prometheus UI easily, such as: - -![Prometheus Metrics List](./../assets/prometheus.png) - - ---- - -## Performance Tuning - -### Kubernetes - -The default K8s setup has limited concurrent requests which limits the overall throughput of the cluster. In this section, we introduced a few parameters that need to be tuned up in order to increase the overall throughput of the cluster. - -#### kubeadm - -Set pod-network mask - -``` -kubeadm init --pod-network-cidr=10.244.0.0/8 -``` - -#### CNI - -Modify CNI mask and resources. - -``` - net-conf.json: | - { - "Network": "10.244.0.0/8", - "Backend": { - "Type": "vxlan" - } - } -``` -``` - resources: - requests: - cpu: "100m" - memory: "200Mi" - limits: - cpu: "100m" - memory: "200Mi" -``` - - -#### Api-Server - -In the Kubernetes API server, we need to modify two parameters: `max-mutating-requests-inflight` and `max-requests-inflight`. Those two parameters represent the API request bandwidth. Because we will generate a large amount of pod request, we need to increase those two parameters. Modify `/etc/kubernetes/manifest/kube-apiserver.yaml`: - -``` ---max-mutating-requests-inflight=3000 ---max-requests-inflight=3000 -``` - -#### Controller-Manager - -In the Kubernetes controller manager, we need to increase the value of three parameters: `node-cidr-mask-size`, `kube-api-burst` and `kube-api-qps`. `kube-api-burst` and `kube-api-qps` control the server side request bandwidth. `node-cidr-mask-size` represents the node CIDR. it needs to be increased as well in order to scale up to thousands of nodes. - - -Modify `/etc/kubernetes/manifest/kube-controller-manager.yaml`: - -``` ---node-cidr-mask-size=21 //log2(max number of pods in cluster) ---kube-api-burst=3000 ---kube-api-qps=3000 -``` - -#### kubelet - -In single worker node, we can run 110 pods as default. But to get higher node resource utilization, we need to add some parameters in Kubelet launch command, and restart it. - -Modify start arg in `/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`, add `--max-Pods=300` behind the start arg and restart - -``` -systemctl daemon-reload -systemctl restart kubelet -``` - ---- - -## Summary - -With Kubemark and Prometheus, we can easily run benchmark testing, collect YuniKorn metrics and analyze the performance. This helps us to identify the performance bottleneck in the scheduler and further eliminate them. The YuniKorn community will continue to improve these tools in the future, and continue to gain more performance improvements. diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/gang_scheduling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/gang_scheduling.md deleted file mode 100644 index 47b57224f85..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/gang_scheduling.md +++ /dev/null @@ -1,285 +0,0 @@ ---- -id: gang_scheduling -title: Gang Scheduling ---- - - - -## What is Gang Scheduling - -When Gang Scheduling is enabled, YuniKorn schedules the app only when -the app’s minimal resource request can be satisfied. Otherwise, apps -will be waiting in the queue. Apps are queued in hierarchy queues, -with gang scheduling enabled, each resource queue is assigned with the -maximum number of applications running concurrently with min resource guaranteed. - -![Gang Scheduling](./../assets/gang_scheduling_iintro.png) - -## Enable Gang Scheduling - -There is no cluster-wide configuration needed to enable Gang Scheduling. -The scheduler actively monitors the metadata of each app, if the app has included -a valid taskGroups definition, it will be considered as gang scheduling desired. - -:::info Task Group -A task group is a “gang” of tasks in an app, these tasks are having the same resource profile -and the same placement constraints. They are considered as homogeneous requests that can be -treated as the same kind in the scheduler. -::: - -### Prerequisite - -For the queues which runs gang scheduling enabled applications, the queue sorting policy needs to be set either -`FIFO` or `StateAware`. To configure queue sorting policy, please refer to doc: [app sorting policies](user_guide/sorting_policies.md#Application_sorting). - -:::info Why FIFO based sorting policy? -When Gang Scheduling is enabled, the scheduler proactively reserves resources -for each application. If the queue sorting policy is not FIFO based (StateAware is FIFO based sorting policy), -the scheduler might reserve partial resources for each app and causing resource segmentation issues. -::: - -### App Configuration - -On Kubernetes, YuniKorn discovers apps by loading metadata from individual pod, the first pod of the app -is required to enclosed with a full copy of app metadata. If the app doesn’t have any notion about the first or second pod, -then all pods are required to carry the same taskGroups info. Gang scheduling requires taskGroups definition, -which can be specified via pod annotations. The required fields are: - -| Annotation | Value | -|----------------------------------------------- |--------------------- | -| yunikorn.apache.org/task-group-name | Task group name, it must be unique within the application | -| yunikorn.apache.org/task-groups | A list of task groups, each item contains all the info defined for the certain task group | -| yunikorn.apache.org/schedulingPolicyParameters | Optional. A arbitrary key value pairs to define scheduling policy parameters. Please read [schedulingPolicyParameters section](#scheduling-policy-parameters) | - -#### How many task groups needed? - -This depends on how many different types of pods this app requests from K8s. A task group is a “gang” of tasks in an app, -these tasks are having the same resource profile and the same placement constraints. They are considered as homogeneous -requests that can be treated as the same kind in the scheduler. Use Spark as an example, each job will need to have 2 task groups, -one for the driver pod and the other one for the executor pods. - -#### How to define task groups? - -The task group definition is a copy of the app’s real pod definition, values for fields like resources, node-selector -and toleration should be the same as the real pods. This is to ensure the scheduler can reserve resources with the -exact correct pod specification. - -#### Scheduling Policy Parameters - -Scheduling policy related configurable parameters. Apply the parameters in the following format in pod's annotation: - -```yaml -annotations: - yunikorn.apache.org/schedulingPolicyParameters: "PARAM1=VALUE1 PARAM2=VALUE2 ..." -``` - -Currently, the following parameters are supported: - -`placeholderTimeoutInSeconds` - -Default value: *15 minutes*. -This parameter defines the reservation timeout for how long the scheduler should wait until giving up allocating all the placeholders. -The timeout timer starts to tick when the scheduler *allocates the first placeholder pod*. This ensures if the scheduler -could not schedule all the placeholder pods, it will eventually give up after a certain amount of time. So that the resources can be -freed up and used by other apps. If non of the placeholders can be allocated, this timeout won't kick-in. To avoid the placeholder -pods stuck forever, please refer to [troubleshooting](trouble_shooting.md#gang-scheduling) for solutions. - -` gangSchedulingStyle` - -Valid values: *Soft*, *Hard* - -Default value: *Soft*. -This parameter defines the fallback mechanism if the app encounters gang issues due to placeholder pod allocation. -See more details in [Gang Scheduling styles](#gang-scheduling-styles) section - -More scheduling parameters will added in order to provide more flexibility while scheduling apps. - -#### Example - -The following example is a yaml file for a job. This job launches 2 pods and each pod sleeps 30 seconds. -The notable change in the pod spec is *spec.template.metadata.annotations*, where we defined `yunikorn.apache.org/task-group-name` -and `yunikorn.apache.org/task-groups`. - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-scheduling-job-example -spec: - completions: 2 - parallelism: 2 - template: - metadata: - labels: - app: sleep - applicationId: "gang-scheduling-job-example" - queue: root.sandbox - annotations: - yunikorn.apache.org/task-group-name: task-group-example - yunikorn.apache.org/task-groups: |- - [{ - "name": "task-group-example", - "minMember": 2, - "minResource": { - "cpu": "100m", - "memory": "50M" - }, - "nodeSelector": {}, - "tolerations": [] - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "50M" -``` - -When this job is submitted to Kubernetes, 2 pods will be created using the same template, and they all belong to one taskGroup: -*“task-group-example”*. YuniKorn will create 2 placeholder pods, each uses the resources specified in the taskGroup definition. -When all 2 placeholders are allocated, the scheduler will bind the the real 2 sleep pods using the spot reserved by the placeholders. - -You can add more than one taskGroups if necessary, each taskGroup is identified by the taskGroup name, -it is required to map each real pod with a pre-defined taskGroup by setting the taskGroup name. Note, -the task group name is only required to be unique within an application. - -### Enable Gang scheduling for Spark jobs - -Each Spark job runs 2 types of pods, driver and executor. Hence, we need to define 2 task groups for each job. -The annotations for the driver pod looks like: - -```yaml -Annotations: - yunikorn.apache.org/schedulingPolicyParameters: “placeholderTimeoutSeconds=30” - yunikorn.apache.org/taskGroupName: “spark-driver” - yunikorn.apache.org/taskGroup: “ - TaskGroups: [ - { - Name: “spark-driver” - minMember: 1, - minResource: { - Cpu: 1, - Memory: 2Gi - }, - Node-selector: ... - Tolerations: ... - }, - { - Name: “spark-executor”, - minMember: 10, - minResource: { - Cpu: 1, - Memory: 2Gi - } - } - ] - ” -``` - -:::note -Spark driver and executor pod has memory overhead, that needs to be considered in the taskGroup resources. -::: - -For all the executor pods, - -```yaml -Annotations: - # the taskGroup name should match to the names - # defined in the taskGroups field - yunikorn.apache.org/taskGroupName: “spark-executor” -``` - -Once the job is submitted to the scheduler, the job won’t be scheduled immediately. -Instead, the scheduler will ensure it gets its minimal resources before actually starting the driver/executors. - -## Gang scheduling Styles - -There are 2 gang scheduling styles supported, Soft and Hard respectively. It can be configured per app-level to define how the app will behave in case the gang scheduling fails. - -- `Hard style`: when this style is used, we will have the initial behavior, more precisely if the application cannot be scheduled according to gang scheduling rules, and it times out, it will be marked as failed, without retrying to schedule it. -- `Soft style`: when the app cannot be gang scheduled, it will fall back to the normal scheduling, and the non-gang scheduling strategy will be used to achieve the best-effort scheduling. When this happens, the app transits to the Resuming state and all the remaining placeholder pods will be cleaned up. - -**Default style used**: `Soft` - -**Enable a specific style**: the style can be changed by setting in the application definition the ‘gangSchedulingStyle’ parameter to Soft or Hard. - -#### Example - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-app-timeout -spec: - completions: 4 - parallelism: 4 - template: - metadata: - labels: - app: sleep - applicationId: gang-app-timeout - queue: fifo - annotations: - yunikorn.apache.org/task-group-name: sched-style - yunikorn.apache.org/schedulingPolicyParameters: "placeholderTimeoutInSeconds=60 gangSchedulingStyle=Hard" - yunikorn.apache.org/task-groups: |- - [{ - "name": "sched-style", - "minMember": 4, - "minResource": { - "cpu": "1", - "memory": "1000M" - }, - "nodeSelector": {}, - "tolerations": [] - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - imagePullPolicy: "IfNotPresent" - command: ["sleep", "30"] - resources: - requests: - cpu: "1" - memory: "1000M" - -``` - -## Verify Configuration - -To verify if the configuration has been done completely and correctly, check the following things: -1. When an app is submitted, verify the expected number of placeholders are created by the scheduler. -If you define 2 task groups, 1 with minMember 1 and the other with minMember 5, that means we are expecting 6 placeholder -gets created once the job is submitted. -2. Verify the placeholder spec is correct. Each placeholder needs to have the same info as the real pod in the same taskGroup. -Check field including: namespace, pod resources, node-selector, and toleration. -3. Verify the placeholders can be allocated on correct type of nodes, and verify the real pods are started by replacing the placeholder pods. - -## Troubleshooting - -Please see the troubleshooting doc when gang scheduling is enabled [here](trouble_shooting.md#gang-scheduling). diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/trouble_shooting.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/trouble_shooting.md deleted file mode 100644 index deada946fcd..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/trouble_shooting.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: trouble_shooting -title: Trouble Shooting ---- - - - -## Scheduler logs - -### Retrieve scheduler logs - -Currently, the scheduler writes its logs to stdout/stderr, docker container handles the redirection of these logs to a -local location on the underneath node, you can read more document [here](https://docs.docker.com/config/containers/logging/configure/). -These logs can be retrieved by [kubectl logs](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs). Such as: - -```shell script -// get the scheduler pod -kubectl get pod -l component=yunikorn-scheduler -n yunikorn -NAME READY STATUS RESTARTS AGE -yunikorn-scheduler-766d7d6cdd-44b82 2/2 Running 0 33h - -// retrieve logs -kubectl logs yunikorn-scheduler-766d7d6cdd-44b82 yunikorn-scheduler-k8s -n yunikorn -``` - -In most cases, this command cannot get all logs because the scheduler is rolling logs very fast. To retrieve more logs in -the past, you will need to setup the [cluster level logging](https://kubernetes.io/docs/concepts/cluster-administration/logging/#cluster-level-logging-architectures). -The recommended setup is to leverage [fluentd](https://www.fluentd.org/) to collect and persistent logs on an external storage, e.g s3. - -### Set Logging Level - -:::note -Changing the logging level requires a restart of the scheduler pod. -::: - -Stop the scheduler: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -``` -edit the deployment config in vim: - -```shell script -kubectl edit deployment yunikorn-scheduler -n yunikorn -``` - -add `LOG_LEVEL` to the `env` field of the container template. For example setting `LOG_LEVEL` to `0` sets the logging -level to `INFO`. - -```yaml -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - ... -spec: - template: - ... - spec: - containers: - - env: - - name: LOG_LEVEL - value: '0' -``` - -Start the scheduler: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -Available logging levels: - -| Value | Logging Level | -|:-----: |:-------------: | -| -1 | DEBUG | -| 0 | INFO | -| 1 | WARN | -| 2 | ERROR | -| 3 | DPanic | -| 4 | Panic | -| 5 | Fatal | - -## Pods are stuck at Pending state - -If some pods are stuck at Pending state, that means the scheduler could not find a node to allocate the pod. There are -several possibilities to cause this: - -### 1. Non of the nodes satisfy pod placement requirement - -A pod can be configured with some placement constraints, such as [node-selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector), -[affinity/anti-affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity), -do not have certain toleration for node [taints](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/), etc. -To debug such issues, you can describe the pod by: - -```shell script -kubectl describe pod -n -``` - -the pod events will contain the predicate failures and that explains why nodes are not qualified for allocation. - -### 2. The queue is running out of capacity - -If the queue is running out of capacity, pods will be pending for available queue resources. To check if a queue is still -having enough capacity for the pending pods, there are several approaches: - -1) check the queue usage from yunikorn UI - -If you do not know how to access the UI, you can refer the document [here](../get_started/get_started.md#访问-web-ui). Go -to the `Queues` page, navigate to the queue where this job is submitted to. You will be able to see the available capacity -left for the queue. - -2) check the pod events - -Run the `kubectl describe pod` to get the pod events. If you see some event like: -`Application does not fit into queue`. That means the pod could not get allocated because the queue -is running out of capacity. - -The pod will be allocated if some other pods in this queue is completed or removed. If the pod remains pending even -the queue has capacity, that may because it is waiting for the cluster to scale up. - -## Restart the scheduler - -YuniKorn can recover its state upon a restart. YuniKorn scheduler pod is deployed as a deployment, restart the scheduler -can be done by scale down and up the replica: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -## Gang Scheduling - -### 1. No placeholders created, app's pods are pending - -*Reason*: This is usually because the app is rejected by the scheduler, therefore non of the pods are scheduled. -The common reasons caused the rejection are: 1) The taskGroups definition is invalid. The scheduler does the -sanity check upon app submission, to ensure all the taskGroups are defined correctly, if these info are malformed, -the scheduler rejects the app; 2) The total min resources defined in the taskGroups is bigger than the queues' max -capacity, scheduler rejects the app because it won't fit into the queue's capacity. Check the pod event for relevant messages, -and you will also be able to find more detail error messages from the schedulers' log. - -*Solution*: Correct the taskGroups definition and retry submitting the app. - -### 2. Not all placeholders can be allocated - -*Reason*: The placeholders also consume resources, if not all of them can be allocated, that usually means either the queue -or the cluster has no sufficient resources for them. In this case, the placeholders will be cleaned up after a certain -amount of time, defined by the `placeholderTimeoutInSeconds` scheduling policy parameter. - -*Solution*: Note, if the placeholder timeout reaches, currently the app will transit to failed state and can not be scheduled -anymore. You can increase the placeholder timeout value if you are willing to wait for a longer time. In the future, a fallback policy -might be added to provide some retry other than failing the app. - -### 3. Not all placeholders are swapped - -*Reason*: This usually means the actual app's pods are less than the minMembers defined in the taskGroups. - -*Solution*: Check the `minMember` in the taskGroup field and ensure it is correctly set. The `minMember` can be less than -the actual pods, setting it to bigger than the actual number of pods is invalid. - -### 4.Placeholders are not cleaned up when the app terminated - -*Reason*: All the placeholders are set an [ownerReference](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents) -to the first real pod of the app, or the controller reference. If the placeholder could not be cleaned up, that means -the garbage collection is not working properly. - -*Solution*: check the placeholder `ownerReference` and the garbage collector in Kubernetes. - - -## Still got questions? - -No problem! The Apache YuniKorn community will be happy to help. You can reach out to the community with the following options: - -1. Post your questions to dev@yunikorn.apache.org -2. Join the [YuniKorn slack channel](https://join.slack.com/t/yunikornworkspace/shared_invite/enQtNzAzMjY0OTI4MjYzLTBmMDdkYTAwNDMwNTE3NWVjZWE1OTczMWE4NDI2Yzg3MmEyZjUyYTZlMDE5M2U4ZjZhNmYyNGFmYjY4ZGYyMGE) and post your questions to the `#yunikorn-user` channel. -3. Join the [community sync up meetings](http://yunikorn.apache.org/community/getInvolved#community-meetings) and directly talk to the community members. \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/workloads/run_spark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/workloads/run_spark.md deleted file mode 100644 index 9f748eb8aaf..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.1/user_guide/workloads/run_spark.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -id: run_spark -title: Run Spark Jobs -description: How to run Spark jobs with YuniKorn -keywords: - - spark ---- - - - -:::note -This document assumes you have YuniKorn and its admission-controller both installed. Please refer to -[get started](../../get_started/get_started.md) to see how that is done. -::: - -## Prepare the docker image for Spark - -To run Spark on Kubernetes, you'll need the Spark docker images. You can 1) use the docker images provided by the YuniKorn -team, or 2) build one from scratch. If you want to build your own Spark docker image, you can -* Download a Spark version that has Kubernetes support, URL: https://github.com/apache/spark -* Build spark with Kubernetes support: -```shell script -mvn -Pyarn -Phadoop-2.7 -Dhadoop.version=2.7.4 -Phive -Pkubernetes -Phive-thriftserver -DskipTests package -``` - -## Create a namespace for Spark jobs - -Create a namespace: - -```shell script -cat < - -This guide gives an overview of how to set up [training-operator](https://github.com/kubeflow/training-operator) -and how to run a Tensorflow job with YuniKorn scheduler. The training-operator is a unified training operator maintained by -Kubeflow. It not only supports TensorFlow but also PyTorch, XGboots, etc. - -## Install training-operator -You can use the following command to install training operator in kubeflow namespace by default. If you have problems with installation, -please refer to [this doc](https://github.com/kubeflow/training-operator#installation) for details. -``` -kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone?ref=v1.3.0" -``` - -## Prepare the docker image -Before you start running a TensorFlow job on Kubernetes, you'll need to build the docker image. -1. Download files from [deployment/examples/tfjob](https://github.com/apache/incubator-yunikorn-k8shim/tree/master/deployments/examples/tfjob) -2. To build this docker image with the following command - -``` -docker build -f Dockerfile -t kubeflow/tf-dist-mnist-test:1.0 . -``` - -## Run a TensorFlow job -Here is a TFJob yaml for MNIST [example](https://github.com/apache/incubator-yunikorn-k8shim/blob/master/deployments/examples/tfjob/tf-job-mnist.yaml). - -```yaml -apiVersion: kubeflow.org/v1 -kind: TFJob -metadata: - name: dist-mnist-for-e2e-test - namespace: kubeflow -spec: - tfReplicaSpecs: - PS: - replicas: 2 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 - Worker: - replicas: 4 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 -``` -Create the TFJob -``` -kubectl create -f deployments/examples/tfjob/tf-job-mnist.yaml -``` -You can view the job info from YuniKorn UI. If you do not know how to access the YuniKorn UI, -please read the document [here](../../get_started/get_started.md#访问-web-ui). - -![tf-job-on-ui](../../assets/tf-job-on-ui.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/assets b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/assets deleted file mode 120000 index 511ac9c0eb8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/assets +++ /dev/null @@ -1 +0,0 @@ -../../../../versioned_docs/version-0.12.1/assets \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/get_started/core_features.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/get_started/core_features.md deleted file mode 100644 index d6d3c497992..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/get_started/core_features.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: core_features -title: 特征 -keywords: - - 特征 ---- - - - -YuniKorn的主要特点包括: - -## 应用感知调度 - -YuniKorn的关键特性之一就是支持应用感知。在默认的K8s调度程序中,它只能根据Pod进行调度,而不能基于用户、作业或者队列进行更细粒度的调度。 -与之不同的是,YuniKorn可以识别用户、作业或者队列,并在做出调度决策时,考虑更多与它们相关的因素,如资源、排序等。 -这使我们能够对资源配额、资源公平性和优先级进行细粒度控制,这是多租户计算系统最重要的需求。 - -## 层次资源队列 - -层次队列提供了一种有效的机制来管理集群资源。 -队列的层次结构可以在逻辑上映射到组织结构。这为不同租户提供了对资源的细粒度控制。 -YuniKorn UI 提供了一个集中的视图来监视资源队列的使用情况,它可以帮助您了解不同租户是如何使用资源的。 -此外,用户可以利用设置最小/最大队列容量来为每个租户设定其弹性资源配额。 - -## 作业排序和排队 - -YuniKorn将每个资源队列中的队列进行排队,排序策略决定哪个应用程序可以首先获得资源。 -这个策略可以是多种多样的,例如简单的 `FIFO`、`Fair`、`StateAware` 或基于 `Priority` 的策略。 -队列可以维持应用的顺序,调度器根据不同的策略为作业分配相应的资源。这种行为更容易被理解和控制。 - -此外,当配置队列最大容量时,作业和任务可以在资源队列中正确排队。 -如果剩余的容量不够,它们可以排队等待,直到释放一些资源。这就简化了客户端操作。 -而在默认调度程序中,资源由命名空间资源配额限制:如果命名空间没有足够的配额,Pod就不能被创建。这是由配额许可控制器强制执行的。 -客户端需要更复杂的逻辑来处理此类场景,例如按条件重试。 - -## 资源公平性 - -在多租户环境中,许多用户共享集群资源。 -为了避免租户争夺资源或者可能的资源不足,需要做到更细粒度的公平性需求,以此来实现跨用户以及跨团队/组织的公平性。 -考虑到权重或优先级,一些更重要的应用可以获得超过其配额的更多的需求资源。 -这往往与资源预算有关,更细粒度的公平模式可以进一步提高资源控制。 - -## 资源预留 - -YuniKorn会自动为未完成的请求进行资源预留。 -如果Pod无法分配,YuniKorn将尝试把它预留在一个满足条件的节点上,并在这个节点上暂时分配该 pod(在尝试其他节点之前)。 -这种机制可以避免这个 Pod 需要的资源被后来提交的更小的、更不挑剔的 Pod 所挤占。 -此功能在批处理工作负载场景中非常重要,因为当对集群提交大量异构 Pod 时,很有可能一些 Pod 会处于“饥饿”状态,即使它们提交得更早。 - -## 吞吐量 - -吞吐量是衡量调度器性能的关键标准。这对于一个大规模的分布式系统来说是至关重要的。 -如果吞吐量不好,应用程序可能会浪费时间等待调度,并进一步影响服务的 SLA(服务级别协议)。 -集群越大,对吞吐量的要求也越高。[基于Kube标记的运行评估](performance/evaluate_perf_function_with_kubemark.md) 章节显示了一些性能数据。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/get_started/get_started.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/get_started/get_started.md deleted file mode 100644 index 035d25def38..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/get_started/get_started.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -id: user_guide -title: 开始 -slug: / ---- - - - -在阅读本指南之前,我们假设您有一个Kubernetes集群或本地 Kubernetes 开发环境,例如 MiniKube。 -还假定 `kubectl` 在您的环境路径内,并且配置正确。 -遵循此 [指南](developer_guide/env_setup.md) 来讲述如何使用 docker-desktop 设置本地Kubernetes集群。 - -## 安装 - -最简单的方法是使用我们的 Helm Chart 在现有的Kubernetes集群上部署YuniKorn。 -我们建议使用 Helm 3 或更高版本。 - -```shell script -helm repo add yunikorn https://apache.github.io/incubator-yunikorn-release -helm repo update -kubectl create namespace yunikorn -helm install yunikorn yunikorn/yunikorn --namespace yunikorn -``` - -默认情况下,Helm Chart 将在集群中安装调度器、web服务器和 admission-controller。 -`admission-controller` 一旦安装,它将把所有集群流量路由到YuniKorn。 -这意味着资源调度会委托给YuniKorn。在Helm安装过程中,可以通过将 `embedAdmissionController` 标志设置为false来禁用它。 - -如果你不想使用 Helm Chart,您可以找到我们的细节教程 [点击这里](developer_guide/deployment.md) 。 - -## 卸载 - -运行如下的命令卸载 YuniKorn: - -```shell script -helm uninstall yunikorn --namespace yunikorn -``` - -## 访问 Web UI - -当部署调度程序时,Web UI 也会部署在容器中。 -我们可以通过以下方式在标准端口上打开 Web 界面的端口转发: - -```shell script -kubectl port-forward svc/yunikorn-service 9889:9889 -n yunikorn -``` - -`9889` 是 Web UI 的默认端口。 -完成此操作后,web UI将在以下地址可用: http://localhost:9889 。 - -![UI 截图](./../assets/yk-ui-screenshots.gif) - -YuniKorn UI 提供了集群资源容量、利用率和所有应用信息的集中视图。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/performance/metrics.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/performance/metrics.md deleted file mode 100644 index 9dedbec73b8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/performance/metrics.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: metrics -title: Scheduler Metrics -keywords: - - metrics ---- - - - -YuniKorn leverages [Prometheus](https://prometheus.io/) to record metrics. The metrics system keeps tracking of -scheduler's critical execution paths, to reveal potential performance bottlenecks. Currently, there are three categories -for these metrics: - -- scheduler: generic metrics of the scheduler, such as allocation latency, num of apps etc. -- queue: each queue has its own metrics sub-system, tracking queue status. -- event: record various changes of events in YuniKorn. - -all metrics are declared in `yunikorn` namespace. -### Scheduler Metrics - -| Metrics Name | Metrics Type | Description | -| --------------------- | ------------ | ------------ | -| containerAllocation | Counter | Total number of attempts to allocate containers. State of the attempt includes `allocated`, `rejected`, `error`, `released`. Increase only. | -| applicationSubmission | Counter | Total number of application submissions. State of the attempt includes `accepted` and `rejected`. Increase only. | -| applicationStatus | Gauge | Total number of application status. State of the application includes `running` and `completed`. | -| totalNodeActive | Gauge | Total number of active nodes. | -| totalNodeFailed | Gauge | Total number of failed nodes. | -| nodeResourceUsage | Gauge | Total resource usage of node, by resource name. | -| schedulingLatency | Histogram | Latency of the main scheduling routine, in seconds. | -| nodeSortingLatency | Histogram | Latency of all nodes sorting, in seconds. | -| appSortingLatency | Histogram | Latency of all applications sorting, in seconds. | -| queueSortingLatency | Histogram | Latency of all queues sorting, in seconds. | -| tryNodeLatency | Histogram | Latency of node condition checks for container allocations, such as placement constraints, in seconds, in seconds. | - -### Queue Metrics - -| Metrics Name | Metrics Type | Description | -| ------------------------- | ------------- | ----------- | -| appMetrics | Counter | Application Metrics, record the total number of applications. State of the application includes `accepted`,`rejected` and `Completed`. | -| usedResourceMetrics | Gauge | Queue used resource. | -| pendingResourceMetrics | Gauge | Queue pending resource. | -| availableResourceMetrics | Gauge | Used resource metrics related to queues etc. | - -### Event Metrics - -| Metrics Name | Metrics Type | Description | -| ------------------------ | ------------ | ----------- | -| totalEventsCreated | Gauge | Total events created. | -| totalEventsChanneled | Gauge | Total events channeled. | -| totalEventsNotChanneled | Gauge | Total events not channeled. | -| totalEventsProcessed | Gauge | Total events processed. | -| totalEventsStored | Gauge | Total events stored. | -| totalEventsNotStored | Gauge | Total events not stored. | -| totalEventsCollected | Gauge | Total events collected. | - -## Access Metrics - -YuniKorn metrics are collected through Prometheus client library, and exposed via scheduler restful service. -Once started, they can be accessed via endpoint http://localhost:9080/ws/v1/metrics. - -## Aggregate Metrics to Prometheus - -It's simple to setup a Prometheus server to grab YuniKorn metrics periodically. Follow these steps: - -- Setup Prometheus (read more from [Prometheus docs](https://prometheus.io/docs/prometheus/latest/installation/)) - -- Configure Prometheus rules: a sample configuration - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] -``` - -- start Prometheus - -```shell script -docker pull prom/prometheus:latest -docker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus -``` - -Use `docker.for.mac.host.internal` instead of `localhost` if you are running Prometheus in a local docker container -on Mac OS. Once started, open Prometheus web UI: http://localhost:9090/graph. You'll see all available metrics from -YuniKorn scheduler. - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/performance/performance_tutorial.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/performance/performance_tutorial.md deleted file mode 100644 index 7d10def46c5..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/performance/performance_tutorial.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -id: performance_tutorial -title: Benchmarking Tutorial -keywords: - - performance - - tutorial ---- - - - -## Overview - -The YuniKorn community continues to optimize the performance of the scheduler, ensuring that YuniKorn satisfies the performance requirements of large-scale batch workloads. Thus, the community has built some useful tools for performance benchmarking that can be reused across releases. This document introduces all these tools and steps to run them. - -## Hardware - -Be aware that performance result is highly variable depending on the underlying hardware. All results published in the doc can only be used as references. We encourage each individual to run similar tests on their own environments in order to get a result based on your own hardware. This doc is just for demonstration purpose. - -A list of servers being used in this test are (Huge thanks to [National Taichung University of Education](http://www.ntcu.edu.tw/newweb/index.htm), [Kuan-Chou Lai](http://www.ntcu.edu.tw/kclai/) for providing these servers for running tests): - -| Manchine Type | CPU | Memory | Download/upload(Mbps) | -| --------------------- | --- | ------ | --------------------- | -| HP | 16 | 36G | 525.74/509.86 | -| HP | 16 | 30G | 564.84/461.82 | -| HP | 16 | 30G | 431.06/511.69 | -| HP | 24 | 32G | 577.31/576.21 | -| IBM blade H22 | 16 | 38G | 432.11/4.15 | -| IBM blade H22 | 16 | 36G | 714.84/4.14 | -| IBM blade H22 | 16 | 42G | 458.38/4.13 | -| IBM blade H22 | 16 | 42G | 445.42/4.13 | -| IBM blade H22 | 16 | 32G | 400.59/4.13 | -| IBM blade H22 | 16 | 12G | 499.87/4.13 | -| IBM blade H23 | 8 | 32G | 468.51/4.14 | -| WS660T | 8 | 16G | 87.73/86.30 | -| ASUSPRO D640MB_M640SA | 4 | 8G | 92.43/93.77 | -| PRO E500 G6_WS720T | 16 | 8G | 90/87.18 | -| WS E500 G6_WS720T | 8 | 40G | 92.61/89.78 | -| E500 G5 | 8 | 8G | 91.34/85.84 | -| WS E500 G5_WS690T | 12 | 16G | 92.2/93.76 | -| WS E500 G5_WS690T | 8 | 32G | 91/89.41 | -| WS E900 G4_SW980T | 80 | 512G | 89.24/87.97 | - -The following steps are needed for each server, otherwise the large scale testing may fail due to the limited number of users/processes/open-files. - -### 1. Set /etc/sysctl.conf -``` -kernel.pid_max=400000 -fs.inotify.max_user_instances=50000 -fs.inotify.max_user_watches=52094 -``` -### 2. Set /etc/security/limits.conf - -``` -* soft nproc 4000000 -* hard nproc 4000000 -root soft nproc 4000000 -root hard nproc 4000000 -* soft nofile 50000 -* hard nofile 50000 -root soft nofile 50000 -root hard nofile 50000 -``` ---- - -## Deploy workflow - -Before going into the details, here are the general steps used in our tests: - -- [Step 1](#Kubernetes): Properly configure Kubernetes API server and controller manager, then add worker nodes. -- [Step 2](#Setup-Kubemark): Deploy hollow pods,which will simulate worker nodes, name hollow nodes. After all hollow nodes in ready status, we need to cordon all native nodes, which are physical presence in the cluster, not the simulated nodes, to avoid we allocated test workload pod to native nodes. -- [Step 3](#Deploy-YuniKorn): Deploy YuniKorn using the Helm chart on the master node, and scale down the Deployment to 0 replica, and [modify the port](#Setup-Prometheus) in `prometheus.yml` to match the port of the service. -- [Step 4](#Run-tests): Deploy 50k Nginx pods for testing, and the API server will create them. But since the YuniKorn scheduler Deployment has been scaled down to 0 replica, all Nginx pods will be stuck in pending. -- [Step 5](../user_guide/trouble_shooting.md#restart-the-scheduler): Scale up The YuniKorn Deployment back to 1 replica, and cordon the master node to avoid YuniKorn allocating Nginx pods there. In this step, YuniKorn will start collecting the metrics. -- [Step 6](#Collect-and-Observe-YuniKorn-metrics): Observe the metrics exposed in Prometheus UI. ---- - -## Setup Kubemark - -[Kubemark](https://github.com/kubernetes/kubernetes/tree/master/test/kubemark) is a performance testing tool which allows users to run experiments on simulated clusters. The primary use case is the scalability testing. The basic idea is to run tens or hundreds of fake kubelet nodes on one physical node in order to simulate large scale clusters. In our tests, we leverage Kubemark to simulate up to a 4K-node cluster on less than 20 physical nodes. - -### 1. Build image - -##### Clone kubernetes repo, and build kubemark binary file - -``` -git clone https://github.com/kubernetes/kubernetes.git -``` -``` -cd kubernetes -``` -``` -KUBE_BUILD_PLATFORMS=linux/amd64 make kubemark GOFLAGS=-v GOGCFLAGS="-N -l" -``` - -##### Copy kubemark binary file to the image folder and build kubemark docker image - -``` -cp _output/bin/kubemark cluster/images/kubemark -``` -``` -IMAGE_TAG=v1.XX.X make build -``` -After this step, you can get the kubemark image which can simulate cluster node. You can upload it to Docker-Hub or just deploy it locally. - -### 2. Install Kubermark - -##### Create kubemark namespace - -``` -kubectl create ns kubemark -``` - -##### Create configmap - -``` -kubectl create configmap node-configmap -n kubemark --from-literal=content.type="test-cluster" -``` - -##### Create secret - -``` -kubectl create secret generic kubeconfig --type=Opaque --namespace=kubemark --from-file=kubelet.kubeconfig={kubeconfig_file_path} --from-file=kubeproxy.kubeconfig={kubeconfig_file_path} -``` -### 3. Label node - -We need to label all native nodes, otherwise the scheduler might allocate hollow pods to other simulated hollow nodes. We can leverage Node selector in yaml to allocate hollow pods to native nodes. - -``` -kubectl label node {node name} tag=tagName -``` - -### 4. Deploy Kubemark - -The hollow-node.yaml is down below, there are some parameters we can configure. - -``` -apiVersion: v1 -kind: ReplicationController -metadata: - name: hollow-node - namespace: kubemark -spec: - replicas: 2000 # the node number you want to simulate - selector: - name: hollow-node - template: - metadata: - labels: - name: hollow-node - spec: - nodeSelector: # leverage label to allocate to native node - tag: tagName - initContainers: - - name: init-inotify-limit - image: docker.io/busybox:latest - imagePullPolicy: IfNotPresent - command: ['sysctl', '-w', 'fs.inotify.max_user_instances=200'] # set as same as max_user_instance in actual node - securityContext: - privileged: true - volumes: - - name: kubeconfig-volume - secret: - secretName: kubeconfig - - name: logs-volume - hostPath: - path: /var/log - containers: - - name: hollow-kubelet - image: 0yukali0/kubemark:1.20.10 # the kubemark image you build - imagePullPolicy: IfNotPresent - ports: - - containerPort: 4194 - - containerPort: 10250 - - containerPort: 10255 - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=kubelet - - --name=$(NODE_NAME) - - --kubeconfig=/kubeconfig/kubelet.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: - requests: # the resource of hollow pod, can modify it. - cpu: 20m - memory: 50M - securityContext: - privileged: true - - name: hollow-proxy - image: 0yukali0/kubemark:1.20.10 # the kubemark image you build - imagePullPolicy: IfNotPresent - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=proxy - - --name=$(NODE_NAME) - - --use-real-proxier=false - - --kubeconfig=/kubeconfig/kubeproxy.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: # the resource of hollow pod, can modify it. - requests: - cpu: 20m - memory: 50M - tolerations: - - effect: NoExecute - key: node.kubernetes.io/unreachable - operator: Exists - - effect: NoExecute - key: node.kubernetes.io/not-ready - operator: Exists -``` - -once done editing, apply it to the cluster: - -``` -kubectl apply -f hollow-node.yaml -``` - ---- - -## Deploy YuniKorn - -#### Install YuniKorn with helm - -We can install YuniKorn with Helm, please refer to this [doc](https://yunikorn.apache.org/docs/#install). -We need to tune some parameters based on the default configuration. We recommend to clone the [release repo](https://github.com/apache/incubator-yunikorn-release) and modify the parameters in `value.yaml`. - -``` -git clone https://github.com/apache/incubator-yunikorn-release.git -cd helm-charts/yunikorn -``` - -#### Configuration - -The modifications in the `value.yaml` are: - -- increased memory/cpu resources for the scheduler pod -- disabled the admission controller -- set the app sorting policy to FAIR - -please see the changes below: - -``` -resources: - requests: - cpu: 14 - memory: 16Gi - limits: - cpu: 14 - memory: 16Gi -``` -``` -embedAdmissionController: false -``` -``` -configuration: | - partitions: - - - name: default - queues: - - name: root - submitacl: '*' - queues: - - - name: sandbox - properties: - application.sort.policy: fair -``` - -#### Install YuniKorn with local release repo - -``` -Helm install yunikorn . --namespace yunikorn -``` - ---- - -## Setup Prometheus - -YuniKorn exposes its scheduling metrics via Prometheus. Thus, we need to set up a Prometheus server to collect these metrics. - -### 1. Download Prometheus release - -``` -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` -``` -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. Configure prometheus.yml - -``` -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] - # 9080 is internal port, need port forward or modify 9080 to service's port -``` - -### 3. Launch Prometheus -``` -./prometheus --config.file=prometheus.yml -``` - ---- -## Run tests - -Once the environment is setup, you are good to run workloads and collect results. YuniKorn community has some useful tools to run workloads and collect metrics, more details will be published here. - ---- - -## Collect and Observe YuniKorn metrics - -After Prometheus is launched, YuniKorn metrics can be easily collected. Here is the [docs](./metrics.md) of YuniKorn metrics. YuniKorn tracks some key scheduling metrics which measure the latency of some critical scheduling paths. These metrics include: - - - **scheduling_latency_seconds:** Latency of the main scheduling routine, in seconds. - - **app_sorting_latency_seconds**: Latency of all applications sorting, in seconds. - - **node_sorting_latency_seconds**: Latency of all nodes sorting, in seconds. - - **queue_sorting_latency_seconds**: Latency of all queues sorting, in seconds. - - **container_allocation_attempt_total**: Total number of attempts to allocate containers. State of the attempt includes `allocated`, `rejected`, `error`, `released`. Increase only. - -you can select and generate graph on Prometheus UI easily, such as: - -![Prometheus Metrics List](./../assets/prometheus.png) - - ---- - -## Performance Tuning - -### Kubernetes - -The default K8s setup has limited concurrent requests which limits the overall throughput of the cluster. In this section, we introduced a few parameters that need to be tuned up in order to increase the overall throughput of the cluster. - -#### kubeadm - -Set pod-network mask - -``` -kubeadm init --pod-network-cidr=10.244.0.0/8 -``` - -#### CNI - -Modify CNI mask and resources. - -``` - net-conf.json: | - { - "Network": "10.244.0.0/8", - "Backend": { - "Type": "vxlan" - } - } -``` -``` - resources: - requests: - cpu: "100m" - memory: "200Mi" - limits: - cpu: "100m" - memory: "200Mi" -``` - - -#### Api-Server - -In the Kubernetes API server, we need to modify two parameters: `max-mutating-requests-inflight` and `max-requests-inflight`. Those two parameters represent the API request bandwidth. Because we will generate a large amount of pod request, we need to increase those two parameters. Modify `/etc/kubernetes/manifest/kube-apiserver.yaml`: - -``` ---max-mutating-requests-inflight=3000 ---max-requests-inflight=3000 -``` - -#### Controller-Manager - -In the Kubernetes controller manager, we need to increase the value of three parameters: `node-cidr-mask-size`, `kube-api-burst` and `kube-api-qps`. `kube-api-burst` and `kube-api-qps` control the server side request bandwidth. `node-cidr-mask-size` represents the node CIDR. it needs to be increased as well in order to scale up to thousands of nodes. - - -Modify `/etc/kubernetes/manifest/kube-controller-manager.yaml`: - -``` ---node-cidr-mask-size=21 //log2(max number of pods in cluster) ---kube-api-burst=3000 ---kube-api-qps=3000 -``` - -#### kubelet - -In single worker node, we can run 110 pods as default. But to get higher node resource utilization, we need to add some parameters in Kubelet launch command, and restart it. - -Modify start arg in `/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`, add `--max-Pods=300` behind the start arg and restart - -``` -systemctl daemon-reload -systemctl restart kubelet -``` - ---- - -## Summary - -With Kubemark and Prometheus, we can easily run benchmark testing, collect YuniKorn metrics and analyze the performance. This helps us to identify the performance bottleneck in the scheduler and further eliminate them. The YuniKorn community will continue to improve these tools in the future, and continue to gain more performance improvements. diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/gang_scheduling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/gang_scheduling.md deleted file mode 100644 index 47b57224f85..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/gang_scheduling.md +++ /dev/null @@ -1,285 +0,0 @@ ---- -id: gang_scheduling -title: Gang Scheduling ---- - - - -## What is Gang Scheduling - -When Gang Scheduling is enabled, YuniKorn schedules the app only when -the app’s minimal resource request can be satisfied. Otherwise, apps -will be waiting in the queue. Apps are queued in hierarchy queues, -with gang scheduling enabled, each resource queue is assigned with the -maximum number of applications running concurrently with min resource guaranteed. - -![Gang Scheduling](./../assets/gang_scheduling_iintro.png) - -## Enable Gang Scheduling - -There is no cluster-wide configuration needed to enable Gang Scheduling. -The scheduler actively monitors the metadata of each app, if the app has included -a valid taskGroups definition, it will be considered as gang scheduling desired. - -:::info Task Group -A task group is a “gang” of tasks in an app, these tasks are having the same resource profile -and the same placement constraints. They are considered as homogeneous requests that can be -treated as the same kind in the scheduler. -::: - -### Prerequisite - -For the queues which runs gang scheduling enabled applications, the queue sorting policy needs to be set either -`FIFO` or `StateAware`. To configure queue sorting policy, please refer to doc: [app sorting policies](user_guide/sorting_policies.md#Application_sorting). - -:::info Why FIFO based sorting policy? -When Gang Scheduling is enabled, the scheduler proactively reserves resources -for each application. If the queue sorting policy is not FIFO based (StateAware is FIFO based sorting policy), -the scheduler might reserve partial resources for each app and causing resource segmentation issues. -::: - -### App Configuration - -On Kubernetes, YuniKorn discovers apps by loading metadata from individual pod, the first pod of the app -is required to enclosed with a full copy of app metadata. If the app doesn’t have any notion about the first or second pod, -then all pods are required to carry the same taskGroups info. Gang scheduling requires taskGroups definition, -which can be specified via pod annotations. The required fields are: - -| Annotation | Value | -|----------------------------------------------- |--------------------- | -| yunikorn.apache.org/task-group-name | Task group name, it must be unique within the application | -| yunikorn.apache.org/task-groups | A list of task groups, each item contains all the info defined for the certain task group | -| yunikorn.apache.org/schedulingPolicyParameters | Optional. A arbitrary key value pairs to define scheduling policy parameters. Please read [schedulingPolicyParameters section](#scheduling-policy-parameters) | - -#### How many task groups needed? - -This depends on how many different types of pods this app requests from K8s. A task group is a “gang” of tasks in an app, -these tasks are having the same resource profile and the same placement constraints. They are considered as homogeneous -requests that can be treated as the same kind in the scheduler. Use Spark as an example, each job will need to have 2 task groups, -one for the driver pod and the other one for the executor pods. - -#### How to define task groups? - -The task group definition is a copy of the app’s real pod definition, values for fields like resources, node-selector -and toleration should be the same as the real pods. This is to ensure the scheduler can reserve resources with the -exact correct pod specification. - -#### Scheduling Policy Parameters - -Scheduling policy related configurable parameters. Apply the parameters in the following format in pod's annotation: - -```yaml -annotations: - yunikorn.apache.org/schedulingPolicyParameters: "PARAM1=VALUE1 PARAM2=VALUE2 ..." -``` - -Currently, the following parameters are supported: - -`placeholderTimeoutInSeconds` - -Default value: *15 minutes*. -This parameter defines the reservation timeout for how long the scheduler should wait until giving up allocating all the placeholders. -The timeout timer starts to tick when the scheduler *allocates the first placeholder pod*. This ensures if the scheduler -could not schedule all the placeholder pods, it will eventually give up after a certain amount of time. So that the resources can be -freed up and used by other apps. If non of the placeholders can be allocated, this timeout won't kick-in. To avoid the placeholder -pods stuck forever, please refer to [troubleshooting](trouble_shooting.md#gang-scheduling) for solutions. - -` gangSchedulingStyle` - -Valid values: *Soft*, *Hard* - -Default value: *Soft*. -This parameter defines the fallback mechanism if the app encounters gang issues due to placeholder pod allocation. -See more details in [Gang Scheduling styles](#gang-scheduling-styles) section - -More scheduling parameters will added in order to provide more flexibility while scheduling apps. - -#### Example - -The following example is a yaml file for a job. This job launches 2 pods and each pod sleeps 30 seconds. -The notable change in the pod spec is *spec.template.metadata.annotations*, where we defined `yunikorn.apache.org/task-group-name` -and `yunikorn.apache.org/task-groups`. - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-scheduling-job-example -spec: - completions: 2 - parallelism: 2 - template: - metadata: - labels: - app: sleep - applicationId: "gang-scheduling-job-example" - queue: root.sandbox - annotations: - yunikorn.apache.org/task-group-name: task-group-example - yunikorn.apache.org/task-groups: |- - [{ - "name": "task-group-example", - "minMember": 2, - "minResource": { - "cpu": "100m", - "memory": "50M" - }, - "nodeSelector": {}, - "tolerations": [] - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "50M" -``` - -When this job is submitted to Kubernetes, 2 pods will be created using the same template, and they all belong to one taskGroup: -*“task-group-example”*. YuniKorn will create 2 placeholder pods, each uses the resources specified in the taskGroup definition. -When all 2 placeholders are allocated, the scheduler will bind the the real 2 sleep pods using the spot reserved by the placeholders. - -You can add more than one taskGroups if necessary, each taskGroup is identified by the taskGroup name, -it is required to map each real pod with a pre-defined taskGroup by setting the taskGroup name. Note, -the task group name is only required to be unique within an application. - -### Enable Gang scheduling for Spark jobs - -Each Spark job runs 2 types of pods, driver and executor. Hence, we need to define 2 task groups for each job. -The annotations for the driver pod looks like: - -```yaml -Annotations: - yunikorn.apache.org/schedulingPolicyParameters: “placeholderTimeoutSeconds=30” - yunikorn.apache.org/taskGroupName: “spark-driver” - yunikorn.apache.org/taskGroup: “ - TaskGroups: [ - { - Name: “spark-driver” - minMember: 1, - minResource: { - Cpu: 1, - Memory: 2Gi - }, - Node-selector: ... - Tolerations: ... - }, - { - Name: “spark-executor”, - minMember: 10, - minResource: { - Cpu: 1, - Memory: 2Gi - } - } - ] - ” -``` - -:::note -Spark driver and executor pod has memory overhead, that needs to be considered in the taskGroup resources. -::: - -For all the executor pods, - -```yaml -Annotations: - # the taskGroup name should match to the names - # defined in the taskGroups field - yunikorn.apache.org/taskGroupName: “spark-executor” -``` - -Once the job is submitted to the scheduler, the job won’t be scheduled immediately. -Instead, the scheduler will ensure it gets its minimal resources before actually starting the driver/executors. - -## Gang scheduling Styles - -There are 2 gang scheduling styles supported, Soft and Hard respectively. It can be configured per app-level to define how the app will behave in case the gang scheduling fails. - -- `Hard style`: when this style is used, we will have the initial behavior, more precisely if the application cannot be scheduled according to gang scheduling rules, and it times out, it will be marked as failed, without retrying to schedule it. -- `Soft style`: when the app cannot be gang scheduled, it will fall back to the normal scheduling, and the non-gang scheduling strategy will be used to achieve the best-effort scheduling. When this happens, the app transits to the Resuming state and all the remaining placeholder pods will be cleaned up. - -**Default style used**: `Soft` - -**Enable a specific style**: the style can be changed by setting in the application definition the ‘gangSchedulingStyle’ parameter to Soft or Hard. - -#### Example - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-app-timeout -spec: - completions: 4 - parallelism: 4 - template: - metadata: - labels: - app: sleep - applicationId: gang-app-timeout - queue: fifo - annotations: - yunikorn.apache.org/task-group-name: sched-style - yunikorn.apache.org/schedulingPolicyParameters: "placeholderTimeoutInSeconds=60 gangSchedulingStyle=Hard" - yunikorn.apache.org/task-groups: |- - [{ - "name": "sched-style", - "minMember": 4, - "minResource": { - "cpu": "1", - "memory": "1000M" - }, - "nodeSelector": {}, - "tolerations": [] - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - imagePullPolicy: "IfNotPresent" - command: ["sleep", "30"] - resources: - requests: - cpu: "1" - memory: "1000M" - -``` - -## Verify Configuration - -To verify if the configuration has been done completely and correctly, check the following things: -1. When an app is submitted, verify the expected number of placeholders are created by the scheduler. -If you define 2 task groups, 1 with minMember 1 and the other with minMember 5, that means we are expecting 6 placeholder -gets created once the job is submitted. -2. Verify the placeholder spec is correct. Each placeholder needs to have the same info as the real pod in the same taskGroup. -Check field including: namespace, pod resources, node-selector, and toleration. -3. Verify the placeholders can be allocated on correct type of nodes, and verify the real pods are started by replacing the placeholder pods. - -## Troubleshooting - -Please see the troubleshooting doc when gang scheduling is enabled [here](trouble_shooting.md#gang-scheduling). diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/trouble_shooting.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/trouble_shooting.md deleted file mode 100644 index deada946fcd..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/trouble_shooting.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: trouble_shooting -title: Trouble Shooting ---- - - - -## Scheduler logs - -### Retrieve scheduler logs - -Currently, the scheduler writes its logs to stdout/stderr, docker container handles the redirection of these logs to a -local location on the underneath node, you can read more document [here](https://docs.docker.com/config/containers/logging/configure/). -These logs can be retrieved by [kubectl logs](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs). Such as: - -```shell script -// get the scheduler pod -kubectl get pod -l component=yunikorn-scheduler -n yunikorn -NAME READY STATUS RESTARTS AGE -yunikorn-scheduler-766d7d6cdd-44b82 2/2 Running 0 33h - -// retrieve logs -kubectl logs yunikorn-scheduler-766d7d6cdd-44b82 yunikorn-scheduler-k8s -n yunikorn -``` - -In most cases, this command cannot get all logs because the scheduler is rolling logs very fast. To retrieve more logs in -the past, you will need to setup the [cluster level logging](https://kubernetes.io/docs/concepts/cluster-administration/logging/#cluster-level-logging-architectures). -The recommended setup is to leverage [fluentd](https://www.fluentd.org/) to collect and persistent logs on an external storage, e.g s3. - -### Set Logging Level - -:::note -Changing the logging level requires a restart of the scheduler pod. -::: - -Stop the scheduler: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -``` -edit the deployment config in vim: - -```shell script -kubectl edit deployment yunikorn-scheduler -n yunikorn -``` - -add `LOG_LEVEL` to the `env` field of the container template. For example setting `LOG_LEVEL` to `0` sets the logging -level to `INFO`. - -```yaml -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - ... -spec: - template: - ... - spec: - containers: - - env: - - name: LOG_LEVEL - value: '0' -``` - -Start the scheduler: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -Available logging levels: - -| Value | Logging Level | -|:-----: |:-------------: | -| -1 | DEBUG | -| 0 | INFO | -| 1 | WARN | -| 2 | ERROR | -| 3 | DPanic | -| 4 | Panic | -| 5 | Fatal | - -## Pods are stuck at Pending state - -If some pods are stuck at Pending state, that means the scheduler could not find a node to allocate the pod. There are -several possibilities to cause this: - -### 1. Non of the nodes satisfy pod placement requirement - -A pod can be configured with some placement constraints, such as [node-selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector), -[affinity/anti-affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity), -do not have certain toleration for node [taints](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/), etc. -To debug such issues, you can describe the pod by: - -```shell script -kubectl describe pod -n -``` - -the pod events will contain the predicate failures and that explains why nodes are not qualified for allocation. - -### 2. The queue is running out of capacity - -If the queue is running out of capacity, pods will be pending for available queue resources. To check if a queue is still -having enough capacity for the pending pods, there are several approaches: - -1) check the queue usage from yunikorn UI - -If you do not know how to access the UI, you can refer the document [here](../get_started/get_started.md#访问-web-ui). Go -to the `Queues` page, navigate to the queue where this job is submitted to. You will be able to see the available capacity -left for the queue. - -2) check the pod events - -Run the `kubectl describe pod` to get the pod events. If you see some event like: -`Application does not fit into queue`. That means the pod could not get allocated because the queue -is running out of capacity. - -The pod will be allocated if some other pods in this queue is completed or removed. If the pod remains pending even -the queue has capacity, that may because it is waiting for the cluster to scale up. - -## Restart the scheduler - -YuniKorn can recover its state upon a restart. YuniKorn scheduler pod is deployed as a deployment, restart the scheduler -can be done by scale down and up the replica: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -## Gang Scheduling - -### 1. No placeholders created, app's pods are pending - -*Reason*: This is usually because the app is rejected by the scheduler, therefore non of the pods are scheduled. -The common reasons caused the rejection are: 1) The taskGroups definition is invalid. The scheduler does the -sanity check upon app submission, to ensure all the taskGroups are defined correctly, if these info are malformed, -the scheduler rejects the app; 2) The total min resources defined in the taskGroups is bigger than the queues' max -capacity, scheduler rejects the app because it won't fit into the queue's capacity. Check the pod event for relevant messages, -and you will also be able to find more detail error messages from the schedulers' log. - -*Solution*: Correct the taskGroups definition and retry submitting the app. - -### 2. Not all placeholders can be allocated - -*Reason*: The placeholders also consume resources, if not all of them can be allocated, that usually means either the queue -or the cluster has no sufficient resources for them. In this case, the placeholders will be cleaned up after a certain -amount of time, defined by the `placeholderTimeoutInSeconds` scheduling policy parameter. - -*Solution*: Note, if the placeholder timeout reaches, currently the app will transit to failed state and can not be scheduled -anymore. You can increase the placeholder timeout value if you are willing to wait for a longer time. In the future, a fallback policy -might be added to provide some retry other than failing the app. - -### 3. Not all placeholders are swapped - -*Reason*: This usually means the actual app's pods are less than the minMembers defined in the taskGroups. - -*Solution*: Check the `minMember` in the taskGroup field and ensure it is correctly set. The `minMember` can be less than -the actual pods, setting it to bigger than the actual number of pods is invalid. - -### 4.Placeholders are not cleaned up when the app terminated - -*Reason*: All the placeholders are set an [ownerReference](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents) -to the first real pod of the app, or the controller reference. If the placeholder could not be cleaned up, that means -the garbage collection is not working properly. - -*Solution*: check the placeholder `ownerReference` and the garbage collector in Kubernetes. - - -## Still got questions? - -No problem! The Apache YuniKorn community will be happy to help. You can reach out to the community with the following options: - -1. Post your questions to dev@yunikorn.apache.org -2. Join the [YuniKorn slack channel](https://join.slack.com/t/yunikornworkspace/shared_invite/enQtNzAzMjY0OTI4MjYzLTBmMDdkYTAwNDMwNTE3NWVjZWE1OTczMWE4NDI2Yzg3MmEyZjUyYTZlMDE5M2U4ZjZhNmYyNGFmYjY4ZGYyMGE) and post your questions to the `#yunikorn-user` channel. -3. Join the [community sync up meetings](http://yunikorn.apache.org/community/getInvolved#community-meetings) and directly talk to the community members. \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/workloads/run_spark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/workloads/run_spark.md deleted file mode 100644 index 9f748eb8aaf..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-0.12.2/user_guide/workloads/run_spark.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -id: run_spark -title: Run Spark Jobs -description: How to run Spark jobs with YuniKorn -keywords: - - spark ---- - - - -:::note -This document assumes you have YuniKorn and its admission-controller both installed. Please refer to -[get started](../../get_started/get_started.md) to see how that is done. -::: - -## Prepare the docker image for Spark - -To run Spark on Kubernetes, you'll need the Spark docker images. You can 1) use the docker images provided by the YuniKorn -team, or 2) build one from scratch. If you want to build your own Spark docker image, you can -* Download a Spark version that has Kubernetes support, URL: https://github.com/apache/spark -* Build spark with Kubernetes support: -```shell script -mvn -Pyarn -Phadoop-2.7 -Dhadoop.version=2.7.4 -Phive -Pkubernetes -Phive-thriftserver -DskipTests package -``` - -## Create a namespace for Spark jobs - -Create a namespace: - -```shell script -cat < - -This guide gives an overview of how to set up [training-operator](https://github.com/kubeflow/training-operator) -and how to run a Tensorflow job with YuniKorn scheduler. The training-operator is a unified training operator maintained by -Kubeflow. It not only supports TensorFlow but also PyTorch, XGboots, etc. - -## Install training-operator -You can use the following command to install training operator in kubeflow namespace by default. If you have problems with installation, -please refer to [this doc](https://github.com/kubeflow/training-operator#installation) for details. -``` -kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone?ref=v1.3.0" -``` - -## Prepare the docker image -Before you start running a TensorFlow job on Kubernetes, you'll need to build the docker image. -1. Download files from [deployment/examples/tfjob](https://github.com/apache/incubator-yunikorn-k8shim/tree/master/deployments/examples/tfjob) -2. To build this docker image with the following command - -``` -docker build -f Dockerfile -t kubeflow/tf-dist-mnist-test:1.0 . -``` - -## Run a TensorFlow job -Here is a TFJob yaml for MNIST [example](https://github.com/apache/incubator-yunikorn-k8shim/blob/master/deployments/examples/tfjob/tf-job-mnist.yaml). - -```yaml -apiVersion: kubeflow.org/v1 -kind: TFJob -metadata: - name: dist-mnist-for-e2e-test - namespace: kubeflow -spec: - tfReplicaSpecs: - PS: - replicas: 2 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 - Worker: - replicas: 4 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 -``` -Create the TFJob -``` -kubectl create -f deployments/examples/tfjob/tf-job-mnist.yaml -``` -You can view the job info from YuniKorn UI. If you do not know how to access the YuniKorn UI, -please read the document [here](../../get_started/get_started.md#访问-web-ui). - -![tf-job-on-ui](../../assets/tf-job-on-ui.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/assets b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/assets deleted file mode 120000 index 271e5348b76..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/assets +++ /dev/null @@ -1 +0,0 @@ -../../../../versioned_docs/version-1.1.0/assets \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/get_started/core_features.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/get_started/core_features.md deleted file mode 100644 index d6d3c497992..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/get_started/core_features.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: core_features -title: 特征 -keywords: - - 特征 ---- - - - -YuniKorn的主要特点包括: - -## 应用感知调度 - -YuniKorn的关键特性之一就是支持应用感知。在默认的K8s调度程序中,它只能根据Pod进行调度,而不能基于用户、作业或者队列进行更细粒度的调度。 -与之不同的是,YuniKorn可以识别用户、作业或者队列,并在做出调度决策时,考虑更多与它们相关的因素,如资源、排序等。 -这使我们能够对资源配额、资源公平性和优先级进行细粒度控制,这是多租户计算系统最重要的需求。 - -## 层次资源队列 - -层次队列提供了一种有效的机制来管理集群资源。 -队列的层次结构可以在逻辑上映射到组织结构。这为不同租户提供了对资源的细粒度控制。 -YuniKorn UI 提供了一个集中的视图来监视资源队列的使用情况,它可以帮助您了解不同租户是如何使用资源的。 -此外,用户可以利用设置最小/最大队列容量来为每个租户设定其弹性资源配额。 - -## 作业排序和排队 - -YuniKorn将每个资源队列中的队列进行排队,排序策略决定哪个应用程序可以首先获得资源。 -这个策略可以是多种多样的,例如简单的 `FIFO`、`Fair`、`StateAware` 或基于 `Priority` 的策略。 -队列可以维持应用的顺序,调度器根据不同的策略为作业分配相应的资源。这种行为更容易被理解和控制。 - -此外,当配置队列最大容量时,作业和任务可以在资源队列中正确排队。 -如果剩余的容量不够,它们可以排队等待,直到释放一些资源。这就简化了客户端操作。 -而在默认调度程序中,资源由命名空间资源配额限制:如果命名空间没有足够的配额,Pod就不能被创建。这是由配额许可控制器强制执行的。 -客户端需要更复杂的逻辑来处理此类场景,例如按条件重试。 - -## 资源公平性 - -在多租户环境中,许多用户共享集群资源。 -为了避免租户争夺资源或者可能的资源不足,需要做到更细粒度的公平性需求,以此来实现跨用户以及跨团队/组织的公平性。 -考虑到权重或优先级,一些更重要的应用可以获得超过其配额的更多的需求资源。 -这往往与资源预算有关,更细粒度的公平模式可以进一步提高资源控制。 - -## 资源预留 - -YuniKorn会自动为未完成的请求进行资源预留。 -如果Pod无法分配,YuniKorn将尝试把它预留在一个满足条件的节点上,并在这个节点上暂时分配该 pod(在尝试其他节点之前)。 -这种机制可以避免这个 Pod 需要的资源被后来提交的更小的、更不挑剔的 Pod 所挤占。 -此功能在批处理工作负载场景中非常重要,因为当对集群提交大量异构 Pod 时,很有可能一些 Pod 会处于“饥饿”状态,即使它们提交得更早。 - -## 吞吐量 - -吞吐量是衡量调度器性能的关键标准。这对于一个大规模的分布式系统来说是至关重要的。 -如果吞吐量不好,应用程序可能会浪费时间等待调度,并进一步影响服务的 SLA(服务级别协议)。 -集群越大,对吞吐量的要求也越高。[基于Kube标记的运行评估](performance/evaluate_perf_function_with_kubemark.md) 章节显示了一些性能数据。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/get_started/get_started.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/get_started/get_started.md deleted file mode 100644 index fcf009f0f5e..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/get_started/get_started.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: user_guide -title: 开始 -slug: / ---- - - - -在阅读本指南之前,我们假设您有一个Kubernetes集群或本地 Kubernetes 开发环境,例如 MiniKube。 -还假定 `kubectl` 在您的环境路径内,并且配置正确。 -遵循此 [指南](developer_guide/env_setup.md) 来讲述如何使用 docker-desktop 设置本地Kubernetes集群。 - -## 安装 - -最简单的方法是使用我们的 Helm Chart 在现有的Kubernetes集群上部署YuniKorn。 -我们建议使用 Helm 3 或更高版本。 - -```shell script -helm repo add yunikorn https://apache.github.io/yunikorn-release -helm repo update -kubectl create namespace yunikorn -helm install yunikorn yunikorn/yunikorn --namespace yunikorn -``` - -默认情况下,Helm Chart 将在集群中安装调度器、web服务器和 admission-controller。 -`admission-controller` 一旦安装,它将把所有集群流量路由到YuniKorn。 -这意味着资源调度会委托给YuniKorn。在Helm安装过程中,可以通过将 `embedAdmissionController` 标志设置为 `false` 来禁用它。 -通过将Helm的 `enableSchedulerPlugin` 标志设置为 `true`,YuniKorn调度器也可以以Kubernetes的调度器插件的方式进行部署。 -这种方式将会部署一个包含与默认调度器一起编译的YuniKorn备用Docker镜像。 -这种新模式借助默认的Kubernetes调度器提供了更好的兼容性,并且适合与将所有调度委托给YuniKorn的 admission-controller 协同使用。 -因为这个模式还是很新的,所以默认没有开启。 - -如果您不确定应该使用哪种部署模式,请参阅我们 [并列比较](user_guide/deployment_modes) 章节的内容。 - -如果你不想使用 Helm Chart,您可以找到我们的细节教程 [点击这里](developer_guide/deployment.md) 。 - -## 卸载 - -运行如下的命令卸载 YuniKorn: - -```shell script -helm uninstall yunikorn --namespace yunikorn -``` - -## 访问 Web UI - -当部署调度程序时,Web UI 也会部署在容器中。 -我们可以通过以下方式在标准端口上打开 Web 界面的端口转发: - -```shell script -kubectl port-forward svc/yunikorn-service 9889:9889 -n yunikorn -``` - -`9889` 是 Web UI 的默认端口。 -完成此操作后,web UI将在以下地址可用: http://localhost:9889 。 - -![UI 截图](./../assets/yk-ui-screenshots.gif) - -YuniKorn UI 提供了集群资源容量、利用率和所有应用信息的集中视图。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/evaluate_perf_function_with_kubemark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/evaluate_perf_function_with_kubemark.md deleted file mode 100644 index 44f4c67ebda..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/evaluate_perf_function_with_kubemark.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: evaluate_perf_function_with_kubemark -title: 使用 Kubemark 评估 YuniKorn 的性能 -keywords: - - 性能 - - 吞吐量 ---- - - - -YuniKorn 社区关注调度程序的性能,并继续在发布时对其进行优化。 社区已经开发了一些工具来反复测试和调整性能。 - -## 环境设置 - -我们利用[Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster)评估调度器的性能。 Kubemark是一个模拟大规模集群的测试工具。 它创建空节点,运行空kubelet以假装原始kubelet行为。 这些空节点上的调度pod不会真正执行。它能够创建一个满足我们实验要求的大集群,揭示yunikorn调度器的性能。 请参阅有关如何设置环境的[详细步骤](performance/performance_tutorial.md)。 - -## 调度程序吞吐量 - -我们在模拟的大规模环境中设计了一些简单的基准测试场景,以评估调度器的性能。 我们的工具测量[吞吐量](https://en.wikipedia.org/wiki/Throughput)并使用这些关键指标来评估性能。 简而言之,调度程序吞吐量是处理pod从在集群上发现它们到将它们分配给节点的速率。 - -在本实验中,我们使用 [Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster) 设置了一个模拟的2000/4000节点集群。然后我们启动10个[部署](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/),每个部署分别设置5000个副本。 这模拟了大规模工作负载同时提交到K8s集群。 我们的工具会定期监控和检查pod状态,随着时间的推移,根据 `podSpec.StartTime` 计算启动的pod数量。 作为对比,我们将相同的实验应用到相同环境中的默认调度程序。 我们看到了YuniKorn相对于默认调度程序的性能优势,如下图所示: - -![Scheduler Throughput](./../assets/yunirkonVSdefault.png) -

图 1. Yunikorn 和默认调度器吞吐量

- -图表记录了集群上所有 Pod 运行所花费的时间: - -| 节点数 | yunikorn | k8s 默认调度器 | 差异 | -|------------------ |:--------------: |:---------------------: |:-----: | -| 2000(节点) | 204(pods/秒) | 49(pods/秒) | 416% | -| 4000(节点) | 115(pods/秒) | 48(pods/秒) | 240% | - -为了使结果标准化,我们已经运行了几轮测试。 如上所示,与默认调度程序相比,YuniKorn实现了`2 倍`~`4 倍`的性能提升。 - -:::note - -与其他性能测试一样,结果因底层硬件而异,例如服务器CPU/内存、网络带宽、I/O速度等。为了获得适用于您的环境的准确结果,我们鼓励您运行这些测试在靠近生产环境的集群上。 - -::: - -## 性能分析 - -我们从实验中得到的结果是有希望的。 我们通过观察更多的YuniKorn内部指标进一步深入分析性能,我们能够找到影响性能的几个关键区域。 - -### K8s 限制 - -我们发现整体性能实际上受到了K8s主服务的限制,例如api-server、controller-manager和etcd,在我们所有的实验中都没有达到YuniKorn的限制。 如果您查看内部调度指标,您可以看到: - -![Allocation latency](./../assets/allocation_4k.png) -

图 2. 4k 节点中的 Yunikorn 指标

- -图2是Prometheus的截图,它记录了YuniKorn中的[内部指标](performance/metrics.md) `containerAllocation`。 它们是调度程序分配的 pod 数量,但不一定绑定到节点。 完成调度50k pod大约需要122秒,即410 pod/秒。 实际吞吐量下降到115个 Pod/秒,额外的时间用于绑定不同节点上的Pod。 如果K8s方面能赶上来,我们会看到更好的结果。 实际上,当我们在大规模集群上调整性能时,我们要做的第一件事就是调整API-server、控制器管理器中的一些参数,以提高吞吐量。 在[性能教程文档](performance/performance_tutorial.md)中查看更多信息。 - -### 节点排序 - -当集群大小增加时,我们看到YuniKorn的性能明显下降。 这是因为在YuniKorn中,我们对集群节点进行了完整排序,以便为给定的pod找到 **“best-fit”** 节点。 这种策略使Pod分布更加优化,基于所使用的 [节点排序策略](./../user_guide/sorting_policies#node-sorting)。 但是,对节点进行排序很昂贵,在调度周期中这样做会产生很多开销。 为了克服这个问题,我们在 [YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807) 中改进了我们的节点排序机制,其背后的想法是使用 [B-Tree ](https://en.wikipedia.org/wiki/B-tree)来存储所有节点并在必要时应用增量更新。 这显着改善了延迟,根据我们的基准测试,这在500、1000、2000 和 5000个节点的集群上分别提高了 35 倍、42 倍、51 倍、74 倍。 - -### 每个节点的前提条件检查 - -在每个调度周期中,另一个耗时的部分是节点的“前提条件检查”。 在这个阶段,YuniKorn评估所有K8s标准断言(Predicates),例如节点选择器、pod亲和性/反亲和性等,以确定pod是否适合节点。 这些评估成本很高。 - -我们做了两个实验来比较启用和禁用断言评估的情况。 请参阅以下结果: - -![Allocation latency](./../assets/predicateComaparation.png) -

图 3. Yunikorn 中的断言效果比较

- -当断言评估被禁用时,吞吐量会提高很多。 我们进一步研究了整个调度周期的延迟分布和断言评估延迟。 并发现: - -![YK predicate latency](./../assets/predicate_4k.png) -

图 4. 断言延迟

- -![YK scheduling with predicate](./../assets/scheduling_with_predicate_4k_.png) -

图 5. 启用断言的调度时间

- -![YK scheduling with no predicate](./../assets/scheduling_no_predicate_4k.png) -

图 6. 不启用断言的调度时间

- -总体而言,YuniKorn 调度周期运行得非常快,每个周期的延迟下降在 **0.001s - 0.01s** 范围内。 并且大部分时间用于断言评估,10倍于调度周期中的其他部分。 - -| | 调度延迟分布(秒) | 断言-评估延迟分布(秒) | -|----------------------- |:---------------------: |:---------------------: | -| 启用断言 | 0.01 - 0.1 | 0.01-0.1 | -| 不启用断言 | 0.001 - 0.01 | 无 | - -## 为什么 YuniKorn 更快? - -默认调度器被创建为面向服务的调度器; 与YuniKorn相比,它在吞吐量方面的敏感性较低。 YuniKorn社区非常努力地保持出色的性能并不断改进。 YuniKorn可以比默认调度器运行得更快的原因是: - -* 短调度周期 - -YuniKorn 保持调度周期短而高效。 YuniKorn 使用所有异步通信协议来确保所有关键路径都是非阻塞调用。 大多数地方只是在进行内存计算,这可能非常高效。 默认调度器利用 [调度框架](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/),它为扩展调度器提供了很大的灵活性,但是,权衡是性能。 调度周期变成了一条很长的链,因为它需要访问所有这些插件。 - -* 异步事件处理 - -YuniKorn利用异步事件处理框架来处理内部状态。 这使得核心调度周期可以快速运行而不会被任何昂贵的调用阻塞。 例如,默认调度程序需要将状态更新、事件写入pod对象,这是在调度周期内完成的。 这涉及将数据持久化到etcd,这可能很慢。 YuniKorn将所有此类事件缓存在一个队列中,并以异步方式写回pod。 - -* 更快的节点排序 - -[YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807)之后,YuniKorn进行了高效的增量节点排序。 这是建立在所谓的基于“资源权重”的节点评分机制之上的,它也可以通过插件进行扩展。 所有这些一起减少了计算节点分数时的开销。 相比之下,默认调度器提供了一些计算节点分数的扩展点,例如`PreScore`、`Score`和`NormalizeScore`。 这些计算量很大,并且在每个调度周期中都会调用它们。 请参阅[代码行](https://github.com/kubernetes/kubernetes/blob/481459d12dc82ab88e413886e2130c2a5e4a8ec4/pkg/scheduler/framework/runtime/framework.go#L857)中的详细信息。 - -## 概括 - -在测试过程中,我们发现YuniKorn的性能非常好,尤其是与默认调度程序相比。 我们已经确定了YuniKorn中可以继续提高性能的主要因素,并解释了为什么YuniKorn的性能优于默认调度程序。 我们还意识到将Kubernetes扩展到数千个节点时的局限性,可以通过使用其他技术(例如联合)来缓解这些局限性。 因此,YuniKorn是一个高效、高吞吐量的调度程序,非常适合在Kubernetes上运行批处理/混合工作负载。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/metrics.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/metrics.md deleted file mode 100644 index 7d6fa73e5b8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/metrics.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: metrics -title: 调度程序指标 -keywords: - - 指标 ---- - - - -YuniKorn利用[Prometheus](https://prometheus.io/) 记录指标。 度量系统不断跟踪调度程序的关键执行路径,以揭示潜在的性能瓶颈。 目前,这些指标分为三类: - -- 调度器:调度器的通用指标,例如分配延迟、应用程序数量等。 -- 队列:每个队列都有自己的指标子系统,跟踪队列状态。 -- 事件:记录YuniKorn中事件的各种变化。 - -所有指标都在`yunikorn`命名空间中声明。 -### 调度程序指标 - -| 指标名称 | 指标类型 | 描述 | -| --------------------- | ------------ | ------------ | -| containerAllocation | Counter | 尝试分配容器的总次数。 尝试状态包括`allocated`, `rejected`, `error`, `released`。 该指标只会增加。 | -| applicationSubmission | Counter | 提交申请的总数。 尝试的状态包括 `accepted`和`rejected`。 该指标只会增加。 | -| applicationStatus | Gauge | 申请状态总数。 应用程序的状态包括`running`和`completed`。 | -| totalNodeActive | Gauge | 活动节点总数。 | -| totalNodeFailed | Gauge | 失败节点的总数。 | -| nodeResourceUsage | Gauge | 节点的总资源使用情况,按资源名称。 | -| schedulingLatency | Histogram | 主调度例程的延迟,以秒为单位。 | -| nodeSortingLatency | Histogram | 所有节点排序的延迟,以秒为单位。 | -| appSortingLatency | Histogram | 所有应用程序排序的延迟,以秒为单位。 | -| queueSortingLatency | Histogram | 所有队列排序的延迟,以秒为单位。 | -| tryNodeLatency | Histogram | 节点条件检查容器分配的延迟,例如放置约束,以秒为单位。 | - -### 队列指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------- | ------------- | ----------- | -| appMetrics | Counter | 应用程序指标,记录申请总数。 应用程序的状态包括`accepted`、`rejected`和`Completed`。 | -| usedResourceMetrics | Gauge | 排队使用的资源。 | -| pendingResourceMetrics | Gauge | 排队等待的资源。 | -| availableResourceMetrics | Gauge | 与队列等相关的已用资源指标。 | - -### 事件指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------ | ------------ | ----------- | -| totalEventsCreated | Gauge | 创建的事件总数。 | -| totalEventsChanneled | Gauge | 引导的事件总数。 | -| totalEventsNotChanneled | Gauge | 引导的事件总数。 | -| totalEventsProcessed | Gauge | 处理的事件总数。 | -| totalEventsStored | Gauge | 存储的事件总数。 | -| totalEventsNotStored | Gauge | 未存储的事件总数。 | -| totalEventsCollected | Gauge | 收集的事件总数。 | - -## 访问指标 - -YuniKorn指标通过Prometheus客户端库收集,并通过调度程序RESTful服务公开。 -启动后,可以通过端点http://localhost:9080/ws/v1/metrics访问它们。 - -## Prometheus 的聚合指标 - -设置 Prometheus 服务器以定期获取 YuniKorn 指标很简单。 按着这些次序: - -- 设置Prometheus(从[Prometheus 文档](https://prometheus.io/docs/prometheus/latest/installation/)了解更多信息) - -- 配置Prometheus规则:示例配置 - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] -``` - -- 启动 Prometheus - -```shell script -docker pull prom/prometheus:latest -docker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus -``` - -如果您在Mac OS上的本地docker容器中运行Prometheus,请使用`docker.for.mac.host.internal`而不是`localhost`。 启动后,打开Prometheus网页界面:http://localhost:9090/graph。 您将看到来自YuniKorn调度程序的所有可用指标。 - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/performance_tutorial.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/performance_tutorial.md deleted file mode 100644 index 32e4df7d012..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/performance_tutorial.md +++ /dev/null @@ -1,451 +0,0 @@ ---- -id: performance_tutorial -title: 基准测试教程 -keywords: - - 性能 - - 教程 ---- - - - -## 概述 - -YuniKorn社区不断优化调度器的性能,确保YuniKorn满足大规模批处理工作负载的性能要求。 因此,社区为性能基准测试构建了一些有用的工具,可以跨版本重用。 本文档介绍了所有这些工具和运行它们的步骤。 - -## 硬件 - -请注意,性能结果因底层硬件而异。 文档中发布的所有结果只能作为参考。 我们鼓励每个人在自己的环境中运行类似的测试,以便根据您自己的硬件获得结果。 本文档仅用于演示目的。 - -本次测试中使用的服务器列表是(非常感谢[国立台中教育大学](http://www.ntcu.edu.tw/newweb/index.htm), [Kuan-Chou Lai](http://www.ntcu.edu.tw/kclai/) 为运行测试提供这些服务器): - -| 机型 | CPU | 内存 | 下载/上传(Mbps) | -| --------------------- | --- | ------ | --------------------- | -| HP | 16 | 36G | 525.74/509.86 | -| HP | 16 | 30G | 564.84/461.82 | -| HP | 16 | 30G | 431.06/511.69 | -| HP | 24 | 32G | 577.31/576.21 | -| IBM blade H22 | 16 | 38G | 432.11/4.15 | -| IBM blade H22 | 16 | 36G | 714.84/4.14 | -| IBM blade H22 | 16 | 42G | 458.38/4.13 | -| IBM blade H22 | 16 | 42G | 445.42/4.13 | -| IBM blade H22 | 16 | 32G | 400.59/4.13 | -| IBM blade H22 | 16 | 12G | 499.87/4.13 | -| IBM blade H23 | 8 | 32G | 468.51/4.14 | -| WS660T | 8 | 16G | 87.73/86.30 | -| ASUSPRO D640MB_M640SA | 4 | 8G | 92.43/93.77 | -| PRO E500 G6_WS720T | 16 | 8G | 90/87.18 | -| WS E500 G6_WS720T | 8 | 40G | 92.61/89.78 | -| E500 G5 | 8 | 8G | 91.34/85.84 | -| WS E500 G5_WS690T | 12 | 16G | 92.2/93.76 | -| WS E500 G5_WS690T | 8 | 32G | 91/89.41 | -| WS E900 G4_SW980T | 80 | 512G | 89.24/87.97 | - -每个服务器都需要执行以下步骤,否则由于用户/进程/打开文件的数量有限,大规模测试可能会失败。 - -### 1. 设置/etc/sysctl.conf -``` -kernel.pid_max=400000 -fs.inotify.max_user_instances=50000 -fs.inotify.max_user_watches=52094 -``` -### 2. 设置/etc/security/limits.conf - -``` -* soft nproc 4000000 -* hard nproc 4000000 -root soft nproc 4000000 -root hard nproc 4000000 -* soft nofile 50000 -* hard nofile 50000 -root soft nofile 50000 -root hard nofile 50000 -``` ---- - -## 部署工作流 - -在进入细节之前,这里是我们测试中使用的一般步骤: - -- [步骤 1](#Kubernetes): 正确配置Kubernetes API服务器和控制器管理器,然后添加工作节点。 -- [步骤 2](#Setup-Kubemark): 部署空pod,将模拟工作节点,命名空节点。 在所有空节点都处于就绪状态后,我们需要封锁(cordon)所有本地节点,这些本地节点是集群中的物理存在,而不是模拟节点,以避免我们将测试工作负载 pod 分配给本地节点。 -- [步骤 3](#Deploy-YuniKorn): 在主节点上使用Helm chart部署YuniKorn,并将 Deployment 缩减为 0 副本,并在`prometheus.yml`中 [修改端口](#Setup-Prometheus) 以匹配服务的端口。 -- [步骤 4](#Run-tests): 部署50k Nginx pod进行测试,API服务器将创建它们。 但是由于YuniKorn调度程序Deployment已经被缩减到0个副本,所有的Nginx pod都将停留在等待状态。 -- [步骤 5](../user_guide/trouble_shooting.md#restart-the-scheduler): 将YuniKorn部署扩展回1个副本,并封锁主节点以避免YuniKorn 在那里分配Nginx pod。 在这一步中,YuniKorn将开始收集指标。 -- [步骤 6](#Collect-and-Observe-YuniKorn-metrics): 观察Prometheus UI中公开的指标。 ---- - -## 设置 Kubemark - -[Kubemark](https://github.com/kubernetes/kubernetes/tree/master/test/kubemark)是一个性能测试工具,允许用户在模拟集群上运行实验。 主要用例是可扩展性测试。 基本思想是在一个物理节点上运行数十或数百个假kubelet节点,以模拟大规模集群。 在我们的测试中,我们利用 Kubemark 在少于20个物理节点上模拟多达4K节点的集群。 - -### 1. 构建镜像 - -##### 克隆kubernetes仓库,并构建kubemark二进制文件 - -``` -git clone https://github.com/kubernetes/kubernetes.git -``` -``` -cd kubernetes -``` -``` -KUBE_BUILD_PLATFORMS=linux/amd64 make kubemark GOFLAGS=-v GOGCFLAGS="-N -l" -``` - -##### 将kubemark二进制文件复制到镜像文件夹并构建kubemark docker镜像 - -``` -cp _output/bin/kubemark cluster/images/kubemark -``` -``` -IMAGE_TAG=v1.XX.X make build -``` -完成此步骤后,您可以获得可以模拟集群节点的kubemark镜像。 您可以将其上传到Docker-Hub或仅在本地部署。 - -### 2. 安装Kubermark - -##### 创建kubemark命名空间 - -``` -kubectl create ns kubemark -``` - -##### 创建configmap - -``` -kubectl create configmap node-configmap -n kubemark --from-literal=content.type="test-cluster" -``` - -##### 创建secret - -``` -kubectl create secret generic kubeconfig --type=Opaque --namespace=kubemark --from-file=kubelet.kubeconfig={kubeconfig_file_path} --from-file=kubeproxy.kubeconfig={kubeconfig_file_path} -``` -### 3. 标签节点 - -我们需要给所有的原生节点打上标签,否则调度器可能会将空pod分配给其他模拟的空节点。 我们可以利用yaml中的节点选择器将空pod分配给本地节点。 - -``` -kubectl label node {node name} tag=tagName -``` - -### 4. 部署Kubemark - -hollow-node.yaml如下所示,我们可以配置一些参数。 - -``` -apiVersion: v1 -kind: ReplicationController -metadata: - name: hollow-node - namespace: kubemark -spec: - replicas: 2000 # 要模拟的节点数 - selector: - name: hollow-node - template: - metadata: - labels: - name: hollow-node - spec: - nodeSelector: # 利用标签分配给本地节点 - tag: tagName - initContainers: - - name: init-inotify-limit - image: docker.io/busybox:latest - imagePullPolicy: IfNotPresent - command: ['sysctl', '-w', 'fs.inotify.max_user_instances=200'] # 设置为与实际节点中的max_user_instance相同 - securityContext: - privileged: true - volumes: - - name: kubeconfig-volume - secret: - secretName: kubeconfig - - name: logs-volume - hostPath: - path: /var/log - containers: - - name: hollow-kubelet - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 4194 - - containerPort: 10250 - - containerPort: 10255 - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=kubelet - - --name=$(NODE_NAME) - - --kubeconfig=/kubeconfig/kubelet.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: - requests: # 空pod的资源,可以修改。 - cpu: 20m - memory: 50M - securityContext: - privileged: true - - name: hollow-proxy - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=proxy - - --name=$(NODE_NAME) - - --use-real-proxier=false - - --kubeconfig=/kubeconfig/kubeproxy.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: # 空pod的资源,可以修改。 - requests: - cpu: 20m - memory: 50M - tolerations: - - effect: NoExecute - key: node.kubernetes.io/unreachable - operator: Exists - - effect: NoExecute - key: node.kubernetes.io/not-ready - operator: Exists -``` - -完成编辑后,将其应用于集群: - -``` -kubectl apply -f hollow-node.yaml -``` - ---- - -## 部署 YuniKorn - -#### 使用helm安装YuniKorn - -我们可以用 Helm 安装 YuniKorn,请参考这个[文档](https://yunikorn.apache.org/docs/#install)。 我们需要根据默认配置调整一些参数。 我们建议克隆[发布仓库](https://github.com/apache/yunikorn-release)并修改`value.yaml`中的参数。 - -``` -git clone https://github.com/apache/yunikorn-release.git -cd helm-charts/yunikorn -``` - -#### 配置 - -`value.yaml`中的修改是: - -- 增加调度程序 pod 的内存/cpu 资源 -- 禁用 admission controller -- 将应用排序策略设置为 FAIR - -请参阅以下更改: - -``` -resources: - requests: - cpu: 14 - memory: 16Gi - limits: - cpu: 14 - memory: 16Gi -``` -``` -embedAdmissionController: false -``` -``` -configuration: | - partitions: - - - name: default - queues: - - name: root - submitacl: '*' - queues: - - - name: sandbox - properties: - application.sort.policy: fair -``` - -#### 使用本地版本库安装YuniKorn - -``` -Helm install yunikorn . --namespace yunikorn -``` - ---- - -## 设置Prometheus - -YuniKorn通过Prometheus公开其调度指标。 因此,我们需要设置一个Prometheus服务器来收集这些指标。 - -### 1. 下载Prometheus版本 - -``` -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` -``` -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. 配置prometheus.yml - -``` -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] - # 9080为内部端口,需要端口转发或修改9080为服务端口 -``` - -### 3. 启动Prometheus -``` -./prometheus --config.file=prometheus.yml -``` - ---- -## 运行测试 - -设置环境后,您就可以运行工作负载并收集结果了。 YuniKorn社区有一些有用的工具来运行工作负载和收集指标,更多详细信息将在此处发布。 - ---- - -## 收集和观察YuniKorn指标 - -Prometheus 启动后,可以轻松收集 YuniKorn 指标。 这是 YuniKorn 指标的[文档](metrics.md)。 YuniKorn 跟踪一些关键调度指标,这些指标衡量一些关键调度路径的延迟。 这些指标包括: - - - **scheduling_latency_seconds:** 主调度例程的延迟,以秒为单位。 - - **app_sorting_latency_seconds**: 所有应用程序排序的延迟,以秒为单位。 - - **node_sorting_latency_seconds**: 所有节点排序的延迟,以秒为单位。 - - **queue_sorting_latency_seconds**: 所有队列排序的延迟,以秒为单位。 - - **container_allocation_attempt_total**: 尝试分配容器的总次数。 尝试状态包括 `allocated`、`rejected`、`error`、`released`。 该指标仅增加。 - -您可以在Prometheus UI上轻松选择和生成图形,例如: - -![Prometheus Metrics List](./../assets/prometheus.png) - - ---- - -## 性能调优 - -### Kubernetes - -默认的 K8s 设置限制了并发请求,这限制了集群的整体吞吐量。 在本节中,我们介绍了一些需要调整的参数,以提高集群的整体吞吐量。 - -#### kubeadm - -设置pod网络掩码 - -``` -kubeadm init --pod-network-cidr=10.244.0.0/8 -``` - -#### CNI - -修改CNI掩码和资源。 - -``` - net-conf.json: | - { - "Network": "10.244.0.0/8", - "Backend": { - "Type": "vxlan" - } - } -``` -``` - resources: - requests: - cpu: "100m" - memory: "200Mi" - limits: - cpu: "100m" - memory: "200Mi" -``` - - -#### Api-Server - -在 Kubernetes API 服务器中,我们需要修改两个参数:`max-mutating-requests-inflight`和`max-requests-inflight`。 这两个参数代表API请求带宽。 因为我们会产生大量的Pod请求,所以我们需要增加这两个参数。修改`/etc/kubernetes/manifest/kube-apiserver.yaml`: - -``` ---max-mutating-requests-inflight=3000 ---max-requests-inflight=3000 -``` - -#### Controller-Manager - -在Kubernetes控制器管理器中,我们需要增加三个参数的值:`node-cidr-mask-size`、`kube-api-burst` `kube-api-qps`. `kube-api-burst`和`kube-api-qps`控制服务器端请求带宽。`node-cidr-mask-size`表示节点 CIDR。 为了扩展到数千个节点,它也需要增加。 - - -Modify `/etc/kubernetes/manifest/kube-controller-manager.yaml`: - -``` ---node-cidr-mask-size=21 //log2(集群中的最大pod数) ---kube-api-burst=3000 ---kube-api-qps=3000 -``` - -#### kubelet - -在单个工作节点中,我们可以默认运行110个pod。 但是为了获得更高的节点资源利用率,我们需要在Kubelet启动命令中添加一些参数,然后重启它。 - -修改`/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`中的起始参数,在起始参数后面添加`--max-Pods=300`并重启。 - -``` -systemctl daemon-reload -systemctl restart kubelet -``` - ---- - -## 概括 - -借助Kubemark和Prometheus,我们可以轻松运行基准测试、收集YuniKorn指标并分析性能。 这有助于我们识别调度程序中的性能瓶颈并进一步消除它们。 YuniKorn社区未来将继续改进这些工具,并继续获得更多的性能改进。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/profiling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/profiling.md deleted file mode 100644 index eb2ae74421a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/performance/profiling.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: profiling -title: 分析 ---- - - - -使用[pprof](https://github.com/google/pprof)做CPU,Memory profiling可以帮助你了解YuniKorn调度器的运行状态。YuniKorn REST服务中添加了分析工具,我们可以轻松地从HTTP端点检索和分析它们。 - -## CPU 分析 - -在这一步,确保你已经运行了YuniKorn,它可以通过`make run`命令从本地运行,也可以部署为在K8s内运行的pod。 然后运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/profile -``` - -配置文件数据将保存在本地文件系统中,一旦完成,它就会进入交互模式。 现在您可以运行分析命令,例如 - -``` -(pprof) top -Showing nodes accounting for 14380ms, 44.85% of 32060ms total -Dropped 145 nodes (cum <= 160.30ms) -Showing top 10 nodes out of 106 - flat flat% sum% cum cum% - 2130ms 6.64% 6.64% 2130ms 6.64% __tsan_read - 1950ms 6.08% 12.73% 1950ms 6.08% __tsan::MetaMap::FreeRange - 1920ms 5.99% 18.71% 1920ms 5.99% __tsan::MetaMap::GetAndLock - 1900ms 5.93% 24.64% 1900ms 5.93% racecall - 1290ms 4.02% 28.67% 1290ms 4.02% __tsan_write - 1090ms 3.40% 32.06% 3270ms 10.20% runtime.mallocgc - 1080ms 3.37% 35.43% 1080ms 3.37% __tsan_func_enter - 1020ms 3.18% 38.62% 1120ms 3.49% runtime.scanobject - 1010ms 3.15% 41.77% 1010ms 3.15% runtime.nanotime - 990ms 3.09% 44.85% 990ms 3.09% __tsan::DenseSlabAlloc::Refill -``` - -您可以键入诸如`web`或`gif`之类的命令来获得可以更好地帮助您的图表 -了解关键代码路径的整体性能。 你可以得到一些东西 -如下所示: - -![CPU Profiling](./../assets/cpu_profile.jpg) - -注意,要使用这些选项,您需要先安装虚拟化工具`graphviz`,如果您使用的是 Mac,只需运行`brew install graphviz`,更多信息请参考[这里](https://graphviz. gitlab.io/)。 - -## 内存分析 - -同样,您可以运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/heap -``` - -这将返回当前堆的快照,允许我们检查内存使用情况。 进入交互模式后,您可以运行一些有用的命令。 比如top可以列出top内存消耗的对象。 -``` -(pprof) top -Showing nodes accounting for 83.58MB, 98.82% of 84.58MB total -Showing top 10 nodes out of 86 - flat flat% sum% cum cum% - 32MB 37.84% 37.84% 32MB 37.84% github.com/apache/yunikorn-core/pkg/cache.NewClusterInfo - 16MB 18.92% 56.75% 16MB 18.92% github.com/apache/yunikorn-core/pkg/rmproxy.NewRMProxy - 16MB 18.92% 75.67% 16MB 18.92% github.com/apache/yunikorn-core/pkg/scheduler.NewScheduler - 16MB 18.92% 94.59% 16MB 18.92% github.com/apache/yunikorn-k8shim/pkg/dispatcher.init.0.func1 - 1.04MB 1.23% 95.81% 1.04MB 1.23% k8s.io/apimachinery/pkg/runtime.(*Scheme).AddKnownTypeWithName - 0.52MB 0.61% 96.43% 0.52MB 0.61% github.com/gogo/protobuf/proto.RegisterType - 0.51MB 0.61% 97.04% 0.51MB 0.61% sync.(*Map).Store - 0.50MB 0.6% 97.63% 0.50MB 0.6% regexp.onePassCopy - 0.50MB 0.59% 98.23% 0.50MB 0.59% github.com/json-iterator/go.(*Iterator).ReadString - 0.50MB 0.59% 98.82% 0.50MB 0.59% text/template/parse.(*Tree).newText -``` - -您还可以运行 `web`、`pdf` 或 `gif` 命令来获取堆图形。 - -## 下载分析样本并在本地进行分析 - -我们在调度程序docker映像中包含了基本的go/go-tool二进制文件,您应该能够进行一些基本的分析 -docker容器内的分析。 但是,如果您想深入研究一些问题,最好进行分析 -本地。 然后您需要先将示例文件复制到本地环境。 复制文件的命令如下: - -``` -kubectl cp ${SCHEDULER_POD_NAME}:${SAMPLE_PATH_IN_DOCKER_CONTAINER} ${LOCAL_COPY_PATH} -``` - -例如 - -``` -kubectl cp yunikorn-scheduler-cf8f8dd8-6szh5:/root/pprof/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -在本地环境中获取文件后,您可以运行“pprof”命令进行分析。 - -``` -go tool pprof /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -## 资源 - -* pprof 文档 https://github.com/google/pprof/tree/master/doc。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/gang_scheduling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/gang_scheduling.md deleted file mode 100644 index f7593a5738b..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/gang_scheduling.md +++ /dev/null @@ -1,288 +0,0 @@ ---- -id: gang_scheduling -title: Gang Scheduling ---- - - - -## What is Gang Scheduling - -When Gang Scheduling is enabled, YuniKorn schedules the app only when -the app’s minimal resource request can be satisfied. Otherwise, apps -will be waiting in the queue. Apps are queued in hierarchy queues, -with gang scheduling enabled, each resource queue is assigned with the -maximum number of applications running concurrently with min resource guaranteed. - -![Gang Scheduling](./../assets/gang_scheduling_iintro.png) - -## Enable Gang Scheduling - -There is no cluster-wide configuration needed to enable Gang Scheduling. -The scheduler actively monitors the metadata of each app, if the app has included -a valid taskGroups definition, it will be considered as gang scheduling desired. - -:::info Task Group -A task group is a “gang” of tasks in an app, these tasks are having the same resource profile -and the same placement constraints. They are considered as homogeneous requests that can be -treated as the same kind in the scheduler. -::: - -### Prerequisite - -For the queues which runs gang scheduling enabled applications, the queue sorting policy needs to be set either -`FIFO` or `StateAware`. To configure queue sorting policy, please refer to doc: [app sorting policies](user_guide/sorting_policies.md#Application_sorting). - -:::info Why FIFO based sorting policy? -When Gang Scheduling is enabled, the scheduler proactively reserves resources -for each application. If the queue sorting policy is not FIFO based (StateAware is FIFO based sorting policy), -the scheduler might reserve partial resources for each app and causing resource segmentation issues. -::: - -### App Configuration - -On Kubernetes, YuniKorn discovers apps by loading metadata from individual pod, the first pod of the app -is required to enclosed with a full copy of app metadata. If the app doesn’t have any notion about the first or second pod, -then all pods are required to carry the same taskGroups info. Gang scheduling requires taskGroups definition, -which can be specified via pod annotations. The required fields are: - -| Annotation | Value | -|----------------------------------------------- |--------------------- | -| yunikorn.apache.org/task-group-name | Task group name, it must be unique within the application | -| yunikorn.apache.org/task-groups | A list of task groups, each item contains all the info defined for the certain task group | -| yunikorn.apache.org/schedulingPolicyParameters | Optional. A arbitrary key value pairs to define scheduling policy parameters. Please read [schedulingPolicyParameters section](#scheduling-policy-parameters) | - -#### How many task groups needed? - -This depends on how many different types of pods this app requests from K8s. A task group is a “gang” of tasks in an app, -these tasks are having the same resource profile and the same placement constraints. They are considered as homogeneous -requests that can be treated as the same kind in the scheduler. Use Spark as an example, each job will need to have 2 task groups, -one for the driver pod and the other one for the executor pods. - -#### How to define task groups? - -The task group definition is a copy of the app’s real pod definition, values for fields like resources, node-selector, toleration -and affinity should be the same as the real pods. This is to ensure the scheduler can reserve resources with the -exact correct pod specification. - -#### Scheduling Policy Parameters - -Scheduling policy related configurable parameters. Apply the parameters in the following format in pod's annotation: - -```yaml -annotations: - yunikorn.apache.org/schedulingPolicyParameters: "PARAM1=VALUE1 PARAM2=VALUE2 ..." -``` - -Currently, the following parameters are supported: - -`placeholderTimeoutInSeconds` - -Default value: *15 minutes*. -This parameter defines the reservation timeout for how long the scheduler should wait until giving up allocating all the placeholders. -The timeout timer starts to tick when the scheduler *allocates the first placeholder pod*. This ensures if the scheduler -could not schedule all the placeholder pods, it will eventually give up after a certain amount of time. So that the resources can be -freed up and used by other apps. If non of the placeholders can be allocated, this timeout won't kick-in. To avoid the placeholder -pods stuck forever, please refer to [troubleshooting](trouble_shooting.md#gang-scheduling) for solutions. - -` gangSchedulingStyle` - -Valid values: *Soft*, *Hard* - -Default value: *Soft*. -This parameter defines the fallback mechanism if the app encounters gang issues due to placeholder pod allocation. -See more details in [Gang Scheduling styles](#gang-scheduling-styles) section - -More scheduling parameters will added in order to provide more flexibility while scheduling apps. - -#### Example - -The following example is a yaml file for a job. This job launches 2 pods and each pod sleeps 30 seconds. -The notable change in the pod spec is *spec.template.metadata.annotations*, where we defined `yunikorn.apache.org/task-group-name` -and `yunikorn.apache.org/task-groups`. - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-scheduling-job-example -spec: - completions: 2 - parallelism: 2 - template: - metadata: - labels: - app: sleep - applicationId: "gang-scheduling-job-example" - queue: root.sandbox - annotations: - yunikorn.apache.org/task-group-name: task-group-example - yunikorn.apache.org/task-groups: |- - [{ - "name": "task-group-example", - "minMember": 2, - "minResource": { - "cpu": "100m", - "memory": "50M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "50M" -``` - -When this job is submitted to Kubernetes, 2 pods will be created using the same template, and they all belong to one taskGroup: -*“task-group-example”*. YuniKorn will create 2 placeholder pods, each uses the resources specified in the taskGroup definition. -When all 2 placeholders are allocated, the scheduler will bind the the real 2 sleep pods using the spot reserved by the placeholders. - -You can add more than one taskGroups if necessary, each taskGroup is identified by the taskGroup name, -it is required to map each real pod with a pre-defined taskGroup by setting the taskGroup name. Note, -the task group name is only required to be unique within an application. - -### Enable Gang scheduling for Spark jobs - -Each Spark job runs 2 types of pods, driver and executor. Hence, we need to define 2 task groups for each job. -The annotations for the driver pod looks like: - -```yaml -Annotations: - yunikorn.apache.org/schedulingPolicyParameters: “placeholderTimeoutSeconds=30” - yunikorn.apache.org/taskGroupName: “spark-driver” - yunikorn.apache.org/taskGroup: “ - TaskGroups: [ - { - Name: “spark-driver”, - minMember: 1, - minResource: { - Cpu: 1, - Memory: 2Gi - }, - Node-selector: ..., - Tolerations: ..., - Affinity: ... - }, - { - Name: “spark-executor”, - minMember: 10, - minResource: { - Cpu: 1, - Memory: 2Gi - } - } - ] - ” -``` - -:::note -Spark driver and executor pod has memory overhead, that needs to be considered in the taskGroup resources. -::: - -For all the executor pods, - -```yaml -Annotations: - # the taskGroup name should match to the names - # defined in the taskGroups field - yunikorn.apache.org/taskGroupName: “spark-executor” -``` - -Once the job is submitted to the scheduler, the job won’t be scheduled immediately. -Instead, the scheduler will ensure it gets its minimal resources before actually starting the driver/executors. - -## Gang scheduling Styles - -There are 2 gang scheduling styles supported, Soft and Hard respectively. It can be configured per app-level to define how the app will behave in case the gang scheduling fails. - -- `Hard style`: when this style is used, we will have the initial behavior, more precisely if the application cannot be scheduled according to gang scheduling rules, and it times out, it will be marked as failed, without retrying to schedule it. -- `Soft style`: when the app cannot be gang scheduled, it will fall back to the normal scheduling, and the non-gang scheduling strategy will be used to achieve the best-effort scheduling. When this happens, the app transits to the Resuming state and all the remaining placeholder pods will be cleaned up. - -**Default style used**: `Soft` - -**Enable a specific style**: the style can be changed by setting in the application definition the ‘gangSchedulingStyle’ parameter to Soft or Hard. - -#### Example - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-app-timeout -spec: - completions: 4 - parallelism: 4 - template: - metadata: - labels: - app: sleep - applicationId: gang-app-timeout - queue: fifo - annotations: - yunikorn.apache.org/task-group-name: sched-style - yunikorn.apache.org/schedulingPolicyParameters: "placeholderTimeoutInSeconds=60 gangSchedulingStyle=Hard" - yunikorn.apache.org/task-groups: |- - [{ - "name": "sched-style", - "minMember": 4, - "minResource": { - "cpu": "1", - "memory": "1000M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - imagePullPolicy: "IfNotPresent" - command: ["sleep", "30"] - resources: - requests: - cpu: "1" - memory: "1000M" - -``` - -## Verify Configuration - -To verify if the configuration has been done completely and correctly, check the following things: -1. When an app is submitted, verify the expected number of placeholders are created by the scheduler. -If you define 2 task groups, 1 with minMember 1 and the other with minMember 5, that means we are expecting 6 placeholder -gets created once the job is submitted. -2. Verify the placeholder spec is correct. Each placeholder needs to have the same info as the real pod in the same taskGroup. -Check field including: namespace, pod resources, node-selector, toleration and affinity. -3. Verify the placeholders can be allocated on correct type of nodes, and verify the real pods are started by replacing the placeholder pods. - -## Troubleshooting - -Please see the troubleshooting doc when gang scheduling is enabled [here](trouble_shooting.md#gang-scheduling). diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/trouble_shooting.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/trouble_shooting.md deleted file mode 100644 index deada946fcd..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/trouble_shooting.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: trouble_shooting -title: Trouble Shooting ---- - - - -## Scheduler logs - -### Retrieve scheduler logs - -Currently, the scheduler writes its logs to stdout/stderr, docker container handles the redirection of these logs to a -local location on the underneath node, you can read more document [here](https://docs.docker.com/config/containers/logging/configure/). -These logs can be retrieved by [kubectl logs](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs). Such as: - -```shell script -// get the scheduler pod -kubectl get pod -l component=yunikorn-scheduler -n yunikorn -NAME READY STATUS RESTARTS AGE -yunikorn-scheduler-766d7d6cdd-44b82 2/2 Running 0 33h - -// retrieve logs -kubectl logs yunikorn-scheduler-766d7d6cdd-44b82 yunikorn-scheduler-k8s -n yunikorn -``` - -In most cases, this command cannot get all logs because the scheduler is rolling logs very fast. To retrieve more logs in -the past, you will need to setup the [cluster level logging](https://kubernetes.io/docs/concepts/cluster-administration/logging/#cluster-level-logging-architectures). -The recommended setup is to leverage [fluentd](https://www.fluentd.org/) to collect and persistent logs on an external storage, e.g s3. - -### Set Logging Level - -:::note -Changing the logging level requires a restart of the scheduler pod. -::: - -Stop the scheduler: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -``` -edit the deployment config in vim: - -```shell script -kubectl edit deployment yunikorn-scheduler -n yunikorn -``` - -add `LOG_LEVEL` to the `env` field of the container template. For example setting `LOG_LEVEL` to `0` sets the logging -level to `INFO`. - -```yaml -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - ... -spec: - template: - ... - spec: - containers: - - env: - - name: LOG_LEVEL - value: '0' -``` - -Start the scheduler: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -Available logging levels: - -| Value | Logging Level | -|:-----: |:-------------: | -| -1 | DEBUG | -| 0 | INFO | -| 1 | WARN | -| 2 | ERROR | -| 3 | DPanic | -| 4 | Panic | -| 5 | Fatal | - -## Pods are stuck at Pending state - -If some pods are stuck at Pending state, that means the scheduler could not find a node to allocate the pod. There are -several possibilities to cause this: - -### 1. Non of the nodes satisfy pod placement requirement - -A pod can be configured with some placement constraints, such as [node-selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector), -[affinity/anti-affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity), -do not have certain toleration for node [taints](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/), etc. -To debug such issues, you can describe the pod by: - -```shell script -kubectl describe pod -n -``` - -the pod events will contain the predicate failures and that explains why nodes are not qualified for allocation. - -### 2. The queue is running out of capacity - -If the queue is running out of capacity, pods will be pending for available queue resources. To check if a queue is still -having enough capacity for the pending pods, there are several approaches: - -1) check the queue usage from yunikorn UI - -If you do not know how to access the UI, you can refer the document [here](../get_started/get_started.md#访问-web-ui). Go -to the `Queues` page, navigate to the queue where this job is submitted to. You will be able to see the available capacity -left for the queue. - -2) check the pod events - -Run the `kubectl describe pod` to get the pod events. If you see some event like: -`Application does not fit into queue`. That means the pod could not get allocated because the queue -is running out of capacity. - -The pod will be allocated if some other pods in this queue is completed or removed. If the pod remains pending even -the queue has capacity, that may because it is waiting for the cluster to scale up. - -## Restart the scheduler - -YuniKorn can recover its state upon a restart. YuniKorn scheduler pod is deployed as a deployment, restart the scheduler -can be done by scale down and up the replica: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -## Gang Scheduling - -### 1. No placeholders created, app's pods are pending - -*Reason*: This is usually because the app is rejected by the scheduler, therefore non of the pods are scheduled. -The common reasons caused the rejection are: 1) The taskGroups definition is invalid. The scheduler does the -sanity check upon app submission, to ensure all the taskGroups are defined correctly, if these info are malformed, -the scheduler rejects the app; 2) The total min resources defined in the taskGroups is bigger than the queues' max -capacity, scheduler rejects the app because it won't fit into the queue's capacity. Check the pod event for relevant messages, -and you will also be able to find more detail error messages from the schedulers' log. - -*Solution*: Correct the taskGroups definition and retry submitting the app. - -### 2. Not all placeholders can be allocated - -*Reason*: The placeholders also consume resources, if not all of them can be allocated, that usually means either the queue -or the cluster has no sufficient resources for them. In this case, the placeholders will be cleaned up after a certain -amount of time, defined by the `placeholderTimeoutInSeconds` scheduling policy parameter. - -*Solution*: Note, if the placeholder timeout reaches, currently the app will transit to failed state and can not be scheduled -anymore. You can increase the placeholder timeout value if you are willing to wait for a longer time. In the future, a fallback policy -might be added to provide some retry other than failing the app. - -### 3. Not all placeholders are swapped - -*Reason*: This usually means the actual app's pods are less than the minMembers defined in the taskGroups. - -*Solution*: Check the `minMember` in the taskGroup field and ensure it is correctly set. The `minMember` can be less than -the actual pods, setting it to bigger than the actual number of pods is invalid. - -### 4.Placeholders are not cleaned up when the app terminated - -*Reason*: All the placeholders are set an [ownerReference](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents) -to the first real pod of the app, or the controller reference. If the placeholder could not be cleaned up, that means -the garbage collection is not working properly. - -*Solution*: check the placeholder `ownerReference` and the garbage collector in Kubernetes. - - -## Still got questions? - -No problem! The Apache YuniKorn community will be happy to help. You can reach out to the community with the following options: - -1. Post your questions to dev@yunikorn.apache.org -2. Join the [YuniKorn slack channel](https://join.slack.com/t/yunikornworkspace/shared_invite/enQtNzAzMjY0OTI4MjYzLTBmMDdkYTAwNDMwNTE3NWVjZWE1OTczMWE4NDI2Yzg3MmEyZjUyYTZlMDE5M2U4ZjZhNmYyNGFmYjY4ZGYyMGE) and post your questions to the `#yunikorn-user` channel. -3. Join the [community sync up meetings](http://yunikorn.apache.org/community/getInvolved#community-meetings) and directly talk to the community members. \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/workloads/run_flink.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/workloads/run_flink.md deleted file mode 100644 index 40eb05b1978..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/workloads/run_flink.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: run_flink -title: 运行Flink作业 -description: 如何与YuniKorn一起运行Flink作业 -image: https://svn.apache.org/repos/asf/flink/site/img/logo/png/100/flink_squirrel_100_color.png -keywords: - - spark ---- - - - -使用 YuniKorn 在 Kubernetes 上运行 [Apache Flink](https://flink.apache.org/) 非常容易。 -根据在 Kubernetes 上运行 Flink 的模式不同,配置会略有不同。 - -## Standalone(独立)模式 - -请关注 [Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/kubernetes.html) 以获取 standalone 部署模式的细节和示例。 -在这种模式下,我们可以直接在 Deployment/Job spec 中添加需要的标签(applicationId 和 queue)来使用 YuniKorn 调度器运行 flink 应用程序,以及 [使用 YuniKorn 调度器运行 workloads](#run-workloads-with-yunikorn-scheduler) . - -## Native(原生)模式 - -请关注 [原生 Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/native_kubernetes.html) 以获取原生部署模式的细节和示例。 -只有 Flink 1.11 或更高版本才支持在 native 模式下使用 YuniKorn 调度程序运行 Flink 应用程序,我们可以利用两个 Flink 配置 `kubernetes.jobmanager.labels` 和 `kubernetes.taskmanager.labels` 来设置所需的标签。 -例子: - -* 启动一个 Flink session -``` -./bin/kubernetes-session.sh \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dresourcemanager.taskmanager-timeout=3600000 \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox -``` - -* 启动一个 Flink application -``` -./bin/flink run-application -p 8 -t kubernetes-application \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dkubernetes.container.image= \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - local:///opt/flink/usrlib/my-flink-job.jar -``` \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/workloads/run_spark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/workloads/run_spark.md deleted file mode 100644 index b7f4f3dedd8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.1.0/user_guide/workloads/run_spark.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -id: run_spark -title: 运行Spark作业 -description: 如何使用YuniKorn运行Spark作业 -keywords: - - spark ---- - - - -:::note 注意 -本文档假设您已安装YuniKorn及其准入控制器。请参阅 [开始](../../get_started/get_started.md) 查看如何操作。 -::: - -## 为Spark准备docker镜像 - -要在Kubernetes上运行Spark,您需要Spark的docker镜像。您可以 -1)使用YuniKorn团队提供的docker镜像 -2)从头开始构建一个镜像。如果你想建立自己的Spark的docker镜像,您可以 -* 下载一个支持Kubernetes的Spark版本,URL: https://github.com/apache/spark -* 构建支持Kubernetes的Spark版本: -```shell script -mvn -Pyarn -Phadoop-2.7 -Dhadoop.version=2.7.4 -Phive -Pkubernetes -Phive-thriftserver -DskipTests package -``` - -## 为Spark作业创建一个命名空间 - -创建一个命名空间: - -```shell script -cat < - -本章节概述了如何设置 [training-operator](https://github.com/kubeflow/training-operator) 以及如何使用 YuniKorn 调度器运行 Tensorflow 作业。 -training-operator 是由 Kubeflow 维护的一体化集成的训练 operator。它不仅支持 TensorFlow,还支持 PyTorch、XGboots 等。 - -## 安装 training-operator -您可以使用以下命令在 kubeflow 命名空间中默认安装 training operator。如果安装有问题, -请参阅 [此文档](https://github.com/kubeflow/training-operator#installation) 来查找相关的详细信息。 -``` -kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone?ref=v1.3.0" -``` - -## 准备 docker 镜像 -在开始于 Kubernetes 上运行 TensorFlow 作业之前,您需要构建 docker 镜像。 -1. 从 [deployment/examples/tfjob](https://github.com/apache/yunikorn-k8shim/tree/master/deployments/examples/tfjob) 上下载文件 -2. 使用以下命令构建这个 docker 镜像 - -``` -docker build -f Dockerfile -t kubeflow/tf-dist-mnist-test:1.0 . -``` - -## 运行一个 TensorFlow 作业 -以下是一个使用 MNIST [样例](https://github.com/apache/yunikorn-k8shim/blob/master/deployments/examples/tfjob/tf-job-mnist.yaml) 的 TFJob yaml. - -```yaml -apiVersion: kubeflow.org/v1 -kind: TFJob -metadata: - name: dist-mnist-for-e2e-test - namespace: kubeflow -spec: - tfReplicaSpecs: - PS: - replicas: 2 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 - Worker: - replicas: 4 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 -``` -创建 TFJob -``` -kubectl create -f deployments/examples/tfjob/tf-job-mnist.yaml -``` - -您可以从 YuniKorn UI 中查看作业信息。 如果您不知道如何访问 YuniKorn UI, -请阅读此 [文档](../../get_started/get_started.md#访问-web-ui)。 - -![tf-job-on-ui](../../assets/tf-job-on-ui.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/api/cluster.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/api/cluster.md deleted file mode 100644 index e81a12d9487..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/api/cluster.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: cluster -title: 集群 ---- - - - -## 集群 - -将回传Yunikorn所管理的集群的信息。信息包括应用程序的数量(包含总数、失败、挂起、正在运行、已完成)和容器的数量,以及资源管理器的构建信息。 - -**位置(URL)** : `/ws/v1/clusters` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**回传代码**:`200 OK` - -**示例** - -在本示例中,响应的内容来自含两个节点的群集,拥有三个应用程序和四个容器以及一个资源管理器。 - - -```json -[ - { - "startTime": 1649167576110754000, - "rmBuildInformation": [ - { - "buildDate": "2022-02-21T19:09:16+0800", - "buildVersion": "latest", - "isPluginVersion": "false", - "rmId": "rm-123" - } - ], - "partition": "default", - "clusterName": "kubernetes", - "totalApplications": "3", - "failedApplications": "1", - "pendingApplications": "", - "runningApplications": "3", - "completedApplications": "", - "totalContainers": "4", - "failedContainers": "", - "pendingContainers": "", - "runningContainers": "4", - "activeNodes": "2", - "totalNodes": "2", - "failedNodes": "" - } -] -``` - -### 出错时的响应 - -**回传代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/assets b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/assets deleted file mode 120000 index 778d0f8e471..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/assets +++ /dev/null @@ -1 +0,0 @@ -../../../../docs/assets \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/get_started/core_features.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/get_started/core_features.md deleted file mode 100644 index d6d3c497992..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/get_started/core_features.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: core_features -title: 特征 -keywords: - - 特征 ---- - - - -YuniKorn的主要特点包括: - -## 应用感知调度 - -YuniKorn的关键特性之一就是支持应用感知。在默认的K8s调度程序中,它只能根据Pod进行调度,而不能基于用户、作业或者队列进行更细粒度的调度。 -与之不同的是,YuniKorn可以识别用户、作业或者队列,并在做出调度决策时,考虑更多与它们相关的因素,如资源、排序等。 -这使我们能够对资源配额、资源公平性和优先级进行细粒度控制,这是多租户计算系统最重要的需求。 - -## 层次资源队列 - -层次队列提供了一种有效的机制来管理集群资源。 -队列的层次结构可以在逻辑上映射到组织结构。这为不同租户提供了对资源的细粒度控制。 -YuniKorn UI 提供了一个集中的视图来监视资源队列的使用情况,它可以帮助您了解不同租户是如何使用资源的。 -此外,用户可以利用设置最小/最大队列容量来为每个租户设定其弹性资源配额。 - -## 作业排序和排队 - -YuniKorn将每个资源队列中的队列进行排队,排序策略决定哪个应用程序可以首先获得资源。 -这个策略可以是多种多样的,例如简单的 `FIFO`、`Fair`、`StateAware` 或基于 `Priority` 的策略。 -队列可以维持应用的顺序,调度器根据不同的策略为作业分配相应的资源。这种行为更容易被理解和控制。 - -此外,当配置队列最大容量时,作业和任务可以在资源队列中正确排队。 -如果剩余的容量不够,它们可以排队等待,直到释放一些资源。这就简化了客户端操作。 -而在默认调度程序中,资源由命名空间资源配额限制:如果命名空间没有足够的配额,Pod就不能被创建。这是由配额许可控制器强制执行的。 -客户端需要更复杂的逻辑来处理此类场景,例如按条件重试。 - -## 资源公平性 - -在多租户环境中,许多用户共享集群资源。 -为了避免租户争夺资源或者可能的资源不足,需要做到更细粒度的公平性需求,以此来实现跨用户以及跨团队/组织的公平性。 -考虑到权重或优先级,一些更重要的应用可以获得超过其配额的更多的需求资源。 -这往往与资源预算有关,更细粒度的公平模式可以进一步提高资源控制。 - -## 资源预留 - -YuniKorn会自动为未完成的请求进行资源预留。 -如果Pod无法分配,YuniKorn将尝试把它预留在一个满足条件的节点上,并在这个节点上暂时分配该 pod(在尝试其他节点之前)。 -这种机制可以避免这个 Pod 需要的资源被后来提交的更小的、更不挑剔的 Pod 所挤占。 -此功能在批处理工作负载场景中非常重要,因为当对集群提交大量异构 Pod 时,很有可能一些 Pod 会处于“饥饿”状态,即使它们提交得更早。 - -## 吞吐量 - -吞吐量是衡量调度器性能的关键标准。这对于一个大规模的分布式系统来说是至关重要的。 -如果吞吐量不好,应用程序可能会浪费时间等待调度,并进一步影响服务的 SLA(服务级别协议)。 -集群越大,对吞吐量的要求也越高。[基于Kube标记的运行评估](performance/evaluate_perf_function_with_kubemark.md) 章节显示了一些性能数据。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/get_started/get_started.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/get_started/get_started.md deleted file mode 100644 index fcf009f0f5e..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/get_started/get_started.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: user_guide -title: 开始 -slug: / ---- - - - -在阅读本指南之前,我们假设您有一个Kubernetes集群或本地 Kubernetes 开发环境,例如 MiniKube。 -还假定 `kubectl` 在您的环境路径内,并且配置正确。 -遵循此 [指南](developer_guide/env_setup.md) 来讲述如何使用 docker-desktop 设置本地Kubernetes集群。 - -## 安装 - -最简单的方法是使用我们的 Helm Chart 在现有的Kubernetes集群上部署YuniKorn。 -我们建议使用 Helm 3 或更高版本。 - -```shell script -helm repo add yunikorn https://apache.github.io/yunikorn-release -helm repo update -kubectl create namespace yunikorn -helm install yunikorn yunikorn/yunikorn --namespace yunikorn -``` - -默认情况下,Helm Chart 将在集群中安装调度器、web服务器和 admission-controller。 -`admission-controller` 一旦安装,它将把所有集群流量路由到YuniKorn。 -这意味着资源调度会委托给YuniKorn。在Helm安装过程中,可以通过将 `embedAdmissionController` 标志设置为 `false` 来禁用它。 -通过将Helm的 `enableSchedulerPlugin` 标志设置为 `true`,YuniKorn调度器也可以以Kubernetes的调度器插件的方式进行部署。 -这种方式将会部署一个包含与默认调度器一起编译的YuniKorn备用Docker镜像。 -这种新模式借助默认的Kubernetes调度器提供了更好的兼容性,并且适合与将所有调度委托给YuniKorn的 admission-controller 协同使用。 -因为这个模式还是很新的,所以默认没有开启。 - -如果您不确定应该使用哪种部署模式,请参阅我们 [并列比较](user_guide/deployment_modes) 章节的内容。 - -如果你不想使用 Helm Chart,您可以找到我们的细节教程 [点击这里](developer_guide/deployment.md) 。 - -## 卸载 - -运行如下的命令卸载 YuniKorn: - -```shell script -helm uninstall yunikorn --namespace yunikorn -``` - -## 访问 Web UI - -当部署调度程序时,Web UI 也会部署在容器中。 -我们可以通过以下方式在标准端口上打开 Web 界面的端口转发: - -```shell script -kubectl port-forward svc/yunikorn-service 9889:9889 -n yunikorn -``` - -`9889` 是 Web UI 的默认端口。 -完成此操作后,web UI将在以下地址可用: http://localhost:9889 。 - -![UI 截图](./../assets/yk-ui-screenshots.gif) - -YuniKorn UI 提供了集群资源容量、利用率和所有应用信息的集中视图。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/evaluate_perf_function_with_kubemark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/evaluate_perf_function_with_kubemark.md deleted file mode 100644 index 44f4c67ebda..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/evaluate_perf_function_with_kubemark.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: evaluate_perf_function_with_kubemark -title: 使用 Kubemark 评估 YuniKorn 的性能 -keywords: - - 性能 - - 吞吐量 ---- - - - -YuniKorn 社区关注调度程序的性能,并继续在发布时对其进行优化。 社区已经开发了一些工具来反复测试和调整性能。 - -## 环境设置 - -我们利用[Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster)评估调度器的性能。 Kubemark是一个模拟大规模集群的测试工具。 它创建空节点,运行空kubelet以假装原始kubelet行为。 这些空节点上的调度pod不会真正执行。它能够创建一个满足我们实验要求的大集群,揭示yunikorn调度器的性能。 请参阅有关如何设置环境的[详细步骤](performance/performance_tutorial.md)。 - -## 调度程序吞吐量 - -我们在模拟的大规模环境中设计了一些简单的基准测试场景,以评估调度器的性能。 我们的工具测量[吞吐量](https://en.wikipedia.org/wiki/Throughput)并使用这些关键指标来评估性能。 简而言之,调度程序吞吐量是处理pod从在集群上发现它们到将它们分配给节点的速率。 - -在本实验中,我们使用 [Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster) 设置了一个模拟的2000/4000节点集群。然后我们启动10个[部署](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/),每个部署分别设置5000个副本。 这模拟了大规模工作负载同时提交到K8s集群。 我们的工具会定期监控和检查pod状态,随着时间的推移,根据 `podSpec.StartTime` 计算启动的pod数量。 作为对比,我们将相同的实验应用到相同环境中的默认调度程序。 我们看到了YuniKorn相对于默认调度程序的性能优势,如下图所示: - -![Scheduler Throughput](./../assets/yunirkonVSdefault.png) -

图 1. Yunikorn 和默认调度器吞吐量

- -图表记录了集群上所有 Pod 运行所花费的时间: - -| 节点数 | yunikorn | k8s 默认调度器 | 差异 | -|------------------ |:--------------: |:---------------------: |:-----: | -| 2000(节点) | 204(pods/秒) | 49(pods/秒) | 416% | -| 4000(节点) | 115(pods/秒) | 48(pods/秒) | 240% | - -为了使结果标准化,我们已经运行了几轮测试。 如上所示,与默认调度程序相比,YuniKorn实现了`2 倍`~`4 倍`的性能提升。 - -:::note - -与其他性能测试一样,结果因底层硬件而异,例如服务器CPU/内存、网络带宽、I/O速度等。为了获得适用于您的环境的准确结果,我们鼓励您运行这些测试在靠近生产环境的集群上。 - -::: - -## 性能分析 - -我们从实验中得到的结果是有希望的。 我们通过观察更多的YuniKorn内部指标进一步深入分析性能,我们能够找到影响性能的几个关键区域。 - -### K8s 限制 - -我们发现整体性能实际上受到了K8s主服务的限制,例如api-server、controller-manager和etcd,在我们所有的实验中都没有达到YuniKorn的限制。 如果您查看内部调度指标,您可以看到: - -![Allocation latency](./../assets/allocation_4k.png) -

图 2. 4k 节点中的 Yunikorn 指标

- -图2是Prometheus的截图,它记录了YuniKorn中的[内部指标](performance/metrics.md) `containerAllocation`。 它们是调度程序分配的 pod 数量,但不一定绑定到节点。 完成调度50k pod大约需要122秒,即410 pod/秒。 实际吞吐量下降到115个 Pod/秒,额外的时间用于绑定不同节点上的Pod。 如果K8s方面能赶上来,我们会看到更好的结果。 实际上,当我们在大规模集群上调整性能时,我们要做的第一件事就是调整API-server、控制器管理器中的一些参数,以提高吞吐量。 在[性能教程文档](performance/performance_tutorial.md)中查看更多信息。 - -### 节点排序 - -当集群大小增加时,我们看到YuniKorn的性能明显下降。 这是因为在YuniKorn中,我们对集群节点进行了完整排序,以便为给定的pod找到 **“best-fit”** 节点。 这种策略使Pod分布更加优化,基于所使用的 [节点排序策略](./../user_guide/sorting_policies#node-sorting)。 但是,对节点进行排序很昂贵,在调度周期中这样做会产生很多开销。 为了克服这个问题,我们在 [YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807) 中改进了我们的节点排序机制,其背后的想法是使用 [B-Tree ](https://en.wikipedia.org/wiki/B-tree)来存储所有节点并在必要时应用增量更新。 这显着改善了延迟,根据我们的基准测试,这在500、1000、2000 和 5000个节点的集群上分别提高了 35 倍、42 倍、51 倍、74 倍。 - -### 每个节点的前提条件检查 - -在每个调度周期中,另一个耗时的部分是节点的“前提条件检查”。 在这个阶段,YuniKorn评估所有K8s标准断言(Predicates),例如节点选择器、pod亲和性/反亲和性等,以确定pod是否适合节点。 这些评估成本很高。 - -我们做了两个实验来比较启用和禁用断言评估的情况。 请参阅以下结果: - -![Allocation latency](./../assets/predicateComaparation.png) -

图 3. Yunikorn 中的断言效果比较

- -当断言评估被禁用时,吞吐量会提高很多。 我们进一步研究了整个调度周期的延迟分布和断言评估延迟。 并发现: - -![YK predicate latency](./../assets/predicate_4k.png) -

图 4. 断言延迟

- -![YK scheduling with predicate](./../assets/scheduling_with_predicate_4k_.png) -

图 5. 启用断言的调度时间

- -![YK scheduling with no predicate](./../assets/scheduling_no_predicate_4k.png) -

图 6. 不启用断言的调度时间

- -总体而言,YuniKorn 调度周期运行得非常快,每个周期的延迟下降在 **0.001s - 0.01s** 范围内。 并且大部分时间用于断言评估,10倍于调度周期中的其他部分。 - -| | 调度延迟分布(秒) | 断言-评估延迟分布(秒) | -|----------------------- |:---------------------: |:---------------------: | -| 启用断言 | 0.01 - 0.1 | 0.01-0.1 | -| 不启用断言 | 0.001 - 0.01 | 无 | - -## 为什么 YuniKorn 更快? - -默认调度器被创建为面向服务的调度器; 与YuniKorn相比,它在吞吐量方面的敏感性较低。 YuniKorn社区非常努力地保持出色的性能并不断改进。 YuniKorn可以比默认调度器运行得更快的原因是: - -* 短调度周期 - -YuniKorn 保持调度周期短而高效。 YuniKorn 使用所有异步通信协议来确保所有关键路径都是非阻塞调用。 大多数地方只是在进行内存计算,这可能非常高效。 默认调度器利用 [调度框架](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/),它为扩展调度器提供了很大的灵活性,但是,权衡是性能。 调度周期变成了一条很长的链,因为它需要访问所有这些插件。 - -* 异步事件处理 - -YuniKorn利用异步事件处理框架来处理内部状态。 这使得核心调度周期可以快速运行而不会被任何昂贵的调用阻塞。 例如,默认调度程序需要将状态更新、事件写入pod对象,这是在调度周期内完成的。 这涉及将数据持久化到etcd,这可能很慢。 YuniKorn将所有此类事件缓存在一个队列中,并以异步方式写回pod。 - -* 更快的节点排序 - -[YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807)之后,YuniKorn进行了高效的增量节点排序。 这是建立在所谓的基于“资源权重”的节点评分机制之上的,它也可以通过插件进行扩展。 所有这些一起减少了计算节点分数时的开销。 相比之下,默认调度器提供了一些计算节点分数的扩展点,例如`PreScore`、`Score`和`NormalizeScore`。 这些计算量很大,并且在每个调度周期中都会调用它们。 请参阅[代码行](https://github.com/kubernetes/kubernetes/blob/481459d12dc82ab88e413886e2130c2a5e4a8ec4/pkg/scheduler/framework/runtime/framework.go#L857)中的详细信息。 - -## 概括 - -在测试过程中,我们发现YuniKorn的性能非常好,尤其是与默认调度程序相比。 我们已经确定了YuniKorn中可以继续提高性能的主要因素,并解释了为什么YuniKorn的性能优于默认调度程序。 我们还意识到将Kubernetes扩展到数千个节点时的局限性,可以通过使用其他技术(例如联合)来缓解这些局限性。 因此,YuniKorn是一个高效、高吞吐量的调度程序,非常适合在Kubernetes上运行批处理/混合工作负载。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/metrics.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/metrics.md deleted file mode 100644 index 7d6fa73e5b8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/metrics.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: metrics -title: 调度程序指标 -keywords: - - 指标 ---- - - - -YuniKorn利用[Prometheus](https://prometheus.io/) 记录指标。 度量系统不断跟踪调度程序的关键执行路径,以揭示潜在的性能瓶颈。 目前,这些指标分为三类: - -- 调度器:调度器的通用指标,例如分配延迟、应用程序数量等。 -- 队列:每个队列都有自己的指标子系统,跟踪队列状态。 -- 事件:记录YuniKorn中事件的各种变化。 - -所有指标都在`yunikorn`命名空间中声明。 -### 调度程序指标 - -| 指标名称 | 指标类型 | 描述 | -| --------------------- | ------------ | ------------ | -| containerAllocation | Counter | 尝试分配容器的总次数。 尝试状态包括`allocated`, `rejected`, `error`, `released`。 该指标只会增加。 | -| applicationSubmission | Counter | 提交申请的总数。 尝试的状态包括 `accepted`和`rejected`。 该指标只会增加。 | -| applicationStatus | Gauge | 申请状态总数。 应用程序的状态包括`running`和`completed`。 | -| totalNodeActive | Gauge | 活动节点总数。 | -| totalNodeFailed | Gauge | 失败节点的总数。 | -| nodeResourceUsage | Gauge | 节点的总资源使用情况,按资源名称。 | -| schedulingLatency | Histogram | 主调度例程的延迟,以秒为单位。 | -| nodeSortingLatency | Histogram | 所有节点排序的延迟,以秒为单位。 | -| appSortingLatency | Histogram | 所有应用程序排序的延迟,以秒为单位。 | -| queueSortingLatency | Histogram | 所有队列排序的延迟,以秒为单位。 | -| tryNodeLatency | Histogram | 节点条件检查容器分配的延迟,例如放置约束,以秒为单位。 | - -### 队列指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------- | ------------- | ----------- | -| appMetrics | Counter | 应用程序指标,记录申请总数。 应用程序的状态包括`accepted`、`rejected`和`Completed`。 | -| usedResourceMetrics | Gauge | 排队使用的资源。 | -| pendingResourceMetrics | Gauge | 排队等待的资源。 | -| availableResourceMetrics | Gauge | 与队列等相关的已用资源指标。 | - -### 事件指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------ | ------------ | ----------- | -| totalEventsCreated | Gauge | 创建的事件总数。 | -| totalEventsChanneled | Gauge | 引导的事件总数。 | -| totalEventsNotChanneled | Gauge | 引导的事件总数。 | -| totalEventsProcessed | Gauge | 处理的事件总数。 | -| totalEventsStored | Gauge | 存储的事件总数。 | -| totalEventsNotStored | Gauge | 未存储的事件总数。 | -| totalEventsCollected | Gauge | 收集的事件总数。 | - -## 访问指标 - -YuniKorn指标通过Prometheus客户端库收集,并通过调度程序RESTful服务公开。 -启动后,可以通过端点http://localhost:9080/ws/v1/metrics访问它们。 - -## Prometheus 的聚合指标 - -设置 Prometheus 服务器以定期获取 YuniKorn 指标很简单。 按着这些次序: - -- 设置Prometheus(从[Prometheus 文档](https://prometheus.io/docs/prometheus/latest/installation/)了解更多信息) - -- 配置Prometheus规则:示例配置 - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] -``` - -- 启动 Prometheus - -```shell script -docker pull prom/prometheus:latest -docker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus -``` - -如果您在Mac OS上的本地docker容器中运行Prometheus,请使用`docker.for.mac.host.internal`而不是`localhost`。 启动后,打开Prometheus网页界面:http://localhost:9090/graph。 您将看到来自YuniKorn调度程序的所有可用指标。 - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/performance_tutorial.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/performance_tutorial.md deleted file mode 100644 index 8180fa0716d..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/performance_tutorial.md +++ /dev/null @@ -1,451 +0,0 @@ ---- -id: performance_tutorial -title: 基准测试教程 -keywords: - - 性能 - - 教程 ---- - - - -## 概述 - -YuniKorn社区不断优化调度器的性能,确保YuniKorn满足大规模批处理工作负载的性能要求。 因此,社区为性能基准测试构建了一些有用的工具,可以跨版本重用。 本文档介绍了所有这些工具和运行它们的步骤。 - -## 硬件 - -请注意,性能结果因底层硬件而异。 文档中发布的所有结果只能作为参考。 我们鼓励每个人在自己的环境中运行类似的测试,以便根据您自己的硬件获得结果。 本文档仅用于演示目的。 - -本次测试中使用的服务器列表是(非常感谢[国立台中教育大学](http://www.ntcu.edu.tw/newweb/index.htm), [Kuan-Chou Lai](http://www.ntcu.edu.tw/kclai/) 为运行测试提供这些服务器): - -| 机型 | CPU | 内存 | 下载/上传(Mbps) | -| --------------------- | --- | ------ | --------------------- | -| HP | 16 | 36G | 525.74/509.86 | -| HP | 16 | 30G | 564.84/461.82 | -| HP | 16 | 30G | 431.06/511.69 | -| HP | 24 | 32G | 577.31/576.21 | -| IBM blade H22 | 16 | 38G | 432.11/4.15 | -| IBM blade H22 | 16 | 36G | 714.84/4.14 | -| IBM blade H22 | 16 | 42G | 458.38/4.13 | -| IBM blade H22 | 16 | 42G | 445.42/4.13 | -| IBM blade H22 | 16 | 32G | 400.59/4.13 | -| IBM blade H22 | 16 | 12G | 499.87/4.13 | -| IBM blade H23 | 8 | 32G | 468.51/4.14 | -| WS660T | 8 | 16G | 87.73/86.30 | -| ASUSPRO D640MB_M640SA | 4 | 8G | 92.43/93.77 | -| PRO E500 G6_WS720T | 16 | 8G | 90/87.18 | -| WS E500 G6_WS720T | 8 | 40G | 92.61/89.78 | -| E500 G5 | 8 | 8G | 91.34/85.84 | -| WS E500 G5_WS690T | 12 | 16G | 92.2/93.76 | -| WS E500 G5_WS690T | 8 | 32G | 91/89.41 | -| WS E900 G4_SW980T | 80 | 512G | 89.24/87.97 | - -每个服务器都需要执行以下步骤,否则由于用户/进程/打开文件的数量有限,大规模测试可能会失败。 - -### 1. 设置/etc/sysctl.conf -``` -kernel.pid_max=400000 -fs.inotify.max_user_instances=50000 -fs.inotify.max_user_watches=52094 -``` -### 2. 设置/etc/security/limits.conf - -``` -* soft nproc 4000000 -* hard nproc 4000000 -root soft nproc 4000000 -root hard nproc 4000000 -* soft nofile 50000 -* hard nofile 50000 -root soft nofile 50000 -root hard nofile 50000 -``` ---- - -## 部署工作流 - -在进入细节之前,这里是我们测试中使用的一般步骤: - -- [步骤 1](#Kubernetes): 正确配置Kubernetes API服务器和控制器管理器,然后添加工作节点。 -- [步骤 2](#Setup-Kubemark): 部署空pod,将模拟工作节点,命名空节点。 在所有空节点都处于就绪状态后,我们需要封锁(cordon)所有本地节点,这些本地节点是集群中的物理存在,而不是模拟节点,以避免我们将测试工作负载 pod 分配给本地节点。 -- [步骤 3](#Deploy-YuniKorn): 在主节点上使用Helm chart部署YuniKorn,并将 Deployment 缩减为 0 副本,并在`prometheus.yml`中 [修改端口](#Setup-Prometheus) 以匹配服务的端口。 -- [步骤 4](#Run-tests): 部署50k Nginx pod进行测试,API服务器将创建它们。 但是由于YuniKorn调度程序Deployment已经被缩减到0个副本,所有的Nginx pod都将停留在等待状态。 -- [步骤 5](../user_guide/troubleshooting.md#restart-the-scheduler): 将YuniKorn部署扩展回1个副本,并封锁主节点以避免YuniKorn 在那里分配Nginx pod。 在这一步中,YuniKorn将开始收集指标。 -- [步骤 6](#Collect-and-Observe-YuniKorn-metrics): 观察Prometheus UI中公开的指标。 ---- - -## 设置 Kubemark - -[Kubemark](https://github.com/kubernetes/kubernetes/tree/master/test/kubemark)是一个性能测试工具,允许用户在模拟集群上运行实验。 主要用例是可扩展性测试。 基本思想是在一个物理节点上运行数十或数百个假kubelet节点,以模拟大规模集群。 在我们的测试中,我们利用 Kubemark 在少于20个物理节点上模拟多达4K节点的集群。 - -### 1. 构建镜像 - -##### 克隆kubernetes仓库,并构建kubemark二进制文件 - -``` -git clone https://github.com/kubernetes/kubernetes.git -``` -``` -cd kubernetes -``` -``` -KUBE_BUILD_PLATFORMS=linux/amd64 make kubemark GOFLAGS=-v GOGCFLAGS="-N -l" -``` - -##### 将kubemark二进制文件复制到镜像文件夹并构建kubemark docker镜像 - -``` -cp _output/bin/kubemark cluster/images/kubemark -``` -``` -IMAGE_TAG=v1.XX.X make build -``` -完成此步骤后,您可以获得可以模拟集群节点的kubemark镜像。 您可以将其上传到Docker-Hub或仅在本地部署。 - -### 2. 安装Kubermark - -##### 创建kubemark命名空间 - -``` -kubectl create ns kubemark -``` - -##### 创建configmap - -``` -kubectl create configmap node-configmap -n kubemark --from-literal=content.type="test-cluster" -``` - -##### 创建secret - -``` -kubectl create secret generic kubeconfig --type=Opaque --namespace=kubemark --from-file=kubelet.kubeconfig={kubeconfig_file_path} --from-file=kubeproxy.kubeconfig={kubeconfig_file_path} -``` -### 3. 标签节点 - -我们需要给所有的原生节点打上标签,否则调度器可能会将空pod分配给其他模拟的空节点。 我们可以利用yaml中的节点选择器将空pod分配给本地节点。 - -``` -kubectl label node {node name} tag=tagName -``` - -### 4. 部署Kubemark - -hollow-node.yaml如下所示,我们可以配置一些参数。 - -``` -apiVersion: v1 -kind: ReplicationController -metadata: - name: hollow-node - namespace: kubemark -spec: - replicas: 2000 # 要模拟的节点数 - selector: - name: hollow-node - template: - metadata: - labels: - name: hollow-node - spec: - nodeSelector: # 利用标签分配给本地节点 - tag: tagName - initContainers: - - name: init-inotify-limit - image: docker.io/busybox:latest - imagePullPolicy: IfNotPresent - command: ['sysctl', '-w', 'fs.inotify.max_user_instances=200'] # 设置为与实际节点中的max_user_instance相同 - securityContext: - privileged: true - volumes: - - name: kubeconfig-volume - secret: - secretName: kubeconfig - - name: logs-volume - hostPath: - path: /var/log - containers: - - name: hollow-kubelet - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 4194 - - containerPort: 10250 - - containerPort: 10255 - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=kubelet - - --name=$(NODE_NAME) - - --kubeconfig=/kubeconfig/kubelet.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: - requests: # 空pod的资源,可以修改。 - cpu: 20m - memory: 50M - securityContext: - privileged: true - - name: hollow-proxy - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=proxy - - --name=$(NODE_NAME) - - --use-real-proxier=false - - --kubeconfig=/kubeconfig/kubeproxy.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: # 空pod的资源,可以修改。 - requests: - cpu: 20m - memory: 50M - tolerations: - - effect: NoExecute - key: node.kubernetes.io/unreachable - operator: Exists - - effect: NoExecute - key: node.kubernetes.io/not-ready - operator: Exists -``` - -完成编辑后,将其应用于集群: - -``` -kubectl apply -f hollow-node.yaml -``` - ---- - -## 部署 YuniKorn - -#### 使用helm安装YuniKorn - -我们可以用 Helm 安装 YuniKorn,请参考这个[文档](https://yunikorn.apache.org/docs/#install)。 我们需要根据默认配置调整一些参数。 我们建议克隆[发布仓库](https://github.com/apache/yunikorn-release)并修改`value.yaml`中的参数。 - -``` -git clone https://github.com/apache/yunikorn-release.git -cd helm-charts/yunikorn -``` - -#### 配置 - -`value.yaml`中的修改是: - -- 增加调度程序 pod 的内存/cpu 资源 -- 禁用 admission controller -- 将应用排序策略设置为 FAIR - -请参阅以下更改: - -``` -resources: - requests: - cpu: 14 - memory: 16Gi - limits: - cpu: 14 - memory: 16Gi -``` -``` -embedAdmissionController: false -``` -``` -configuration: | - partitions: - - - name: default - queues: - - name: root - submitacl: '*' - queues: - - - name: sandbox - properties: - application.sort.policy: fair -``` - -#### 使用本地版本库安装YuniKorn - -``` -Helm install yunikorn . --namespace yunikorn -``` - ---- - -## 设置Prometheus - -YuniKorn通过Prometheus公开其调度指标。 因此,我们需要设置一个Prometheus服务器来收集这些指标。 - -### 1. 下载Prometheus版本 - -``` -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` -``` -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. 配置prometheus.yml - -``` -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] - # 9080为内部端口,需要端口转发或修改9080为服务端口 -``` - -### 3. 启动Prometheus -``` -./prometheus --config.file=prometheus.yml -``` - ---- -## 运行测试 - -设置环境后,您就可以运行工作负载并收集结果了。 YuniKorn社区有一些有用的工具来运行工作负载和收集指标,更多详细信息将在此处发布。 - ---- - -## 收集和观察YuniKorn指标 - -Prometheus 启动后,可以轻松收集 YuniKorn 指标。 这是 YuniKorn 指标的[文档](metrics.md)。 YuniKorn 跟踪一些关键调度指标,这些指标衡量一些关键调度路径的延迟。 这些指标包括: - - - **scheduling_latency_seconds:** 主调度例程的延迟,以秒为单位。 - - **app_sorting_latency_seconds**: 所有应用程序排序的延迟,以秒为单位。 - - **node_sorting_latency_seconds**: 所有节点排序的延迟,以秒为单位。 - - **queue_sorting_latency_seconds**: 所有队列排序的延迟,以秒为单位。 - - **container_allocation_attempt_total**: 尝试分配容器的总次数。 尝试状态包括 `allocated`、`rejected`、`error`、`released`。 该指标仅增加。 - -您可以在Prometheus UI上轻松选择和生成图形,例如: - -![Prometheus Metrics List](./../assets/prometheus.png) - - ---- - -## 性能调优 - -### Kubernetes - -默认的 K8s 设置限制了并发请求,这限制了集群的整体吞吐量。 在本节中,我们介绍了一些需要调整的参数,以提高集群的整体吞吐量。 - -#### kubeadm - -设置pod网络掩码 - -``` -kubeadm init --pod-network-cidr=10.244.0.0/8 -``` - -#### CNI - -修改CNI掩码和资源。 - -``` - net-conf.json: | - { - "Network": "10.244.0.0/8", - "Backend": { - "Type": "vxlan" - } - } -``` -``` - resources: - requests: - cpu: "100m" - memory: "200Mi" - limits: - cpu: "100m" - memory: "200Mi" -``` - - -#### Api-Server - -在 Kubernetes API 服务器中,我们需要修改两个参数:`max-mutating-requests-inflight`和`max-requests-inflight`。 这两个参数代表API请求带宽。 因为我们会产生大量的Pod请求,所以我们需要增加这两个参数。修改`/etc/kubernetes/manifest/kube-apiserver.yaml`: - -``` ---max-mutating-requests-inflight=3000 ---max-requests-inflight=3000 -``` - -#### Controller-Manager - -在Kubernetes控制器管理器中,我们需要增加三个参数的值:`node-cidr-mask-size`、`kube-api-burst` `kube-api-qps`. `kube-api-burst`和`kube-api-qps`控制服务器端请求带宽。`node-cidr-mask-size`表示节点 CIDR。 为了扩展到数千个节点,它也需要增加。 - - -Modify `/etc/kubernetes/manifest/kube-controller-manager.yaml`: - -``` ---node-cidr-mask-size=21 //log2(集群中的最大pod数) ---kube-api-burst=3000 ---kube-api-qps=3000 -``` - -#### kubelet - -在单个工作节点中,我们可以默认运行110个pod。 但是为了获得更高的节点资源利用率,我们需要在Kubelet启动命令中添加一些参数,然后重启它。 - -修改`/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`中的起始参数,在起始参数后面添加`--max-Pods=300`并重启。 - -``` -systemctl daemon-reload -systemctl restart kubelet -``` - ---- - -## 概括 - -借助Kubemark和Prometheus,我们可以轻松运行基准测试、收集YuniKorn指标并分析性能。 这有助于我们识别调度程序中的性能瓶颈并进一步消除它们。 YuniKorn社区未来将继续改进这些工具,并继续获得更多的性能改进。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/profiling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/profiling.md deleted file mode 100644 index eb2ae74421a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/performance/profiling.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: profiling -title: 分析 ---- - - - -使用[pprof](https://github.com/google/pprof)做CPU,Memory profiling可以帮助你了解YuniKorn调度器的运行状态。YuniKorn REST服务中添加了分析工具,我们可以轻松地从HTTP端点检索和分析它们。 - -## CPU 分析 - -在这一步,确保你已经运行了YuniKorn,它可以通过`make run`命令从本地运行,也可以部署为在K8s内运行的pod。 然后运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/profile -``` - -配置文件数据将保存在本地文件系统中,一旦完成,它就会进入交互模式。 现在您可以运行分析命令,例如 - -``` -(pprof) top -Showing nodes accounting for 14380ms, 44.85% of 32060ms total -Dropped 145 nodes (cum <= 160.30ms) -Showing top 10 nodes out of 106 - flat flat% sum% cum cum% - 2130ms 6.64% 6.64% 2130ms 6.64% __tsan_read - 1950ms 6.08% 12.73% 1950ms 6.08% __tsan::MetaMap::FreeRange - 1920ms 5.99% 18.71% 1920ms 5.99% __tsan::MetaMap::GetAndLock - 1900ms 5.93% 24.64% 1900ms 5.93% racecall - 1290ms 4.02% 28.67% 1290ms 4.02% __tsan_write - 1090ms 3.40% 32.06% 3270ms 10.20% runtime.mallocgc - 1080ms 3.37% 35.43% 1080ms 3.37% __tsan_func_enter - 1020ms 3.18% 38.62% 1120ms 3.49% runtime.scanobject - 1010ms 3.15% 41.77% 1010ms 3.15% runtime.nanotime - 990ms 3.09% 44.85% 990ms 3.09% __tsan::DenseSlabAlloc::Refill -``` - -您可以键入诸如`web`或`gif`之类的命令来获得可以更好地帮助您的图表 -了解关键代码路径的整体性能。 你可以得到一些东西 -如下所示: - -![CPU Profiling](./../assets/cpu_profile.jpg) - -注意,要使用这些选项,您需要先安装虚拟化工具`graphviz`,如果您使用的是 Mac,只需运行`brew install graphviz`,更多信息请参考[这里](https://graphviz. gitlab.io/)。 - -## 内存分析 - -同样,您可以运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/heap -``` - -这将返回当前堆的快照,允许我们检查内存使用情况。 进入交互模式后,您可以运行一些有用的命令。 比如top可以列出top内存消耗的对象。 -``` -(pprof) top -Showing nodes accounting for 83.58MB, 98.82% of 84.58MB total -Showing top 10 nodes out of 86 - flat flat% sum% cum cum% - 32MB 37.84% 37.84% 32MB 37.84% github.com/apache/yunikorn-core/pkg/cache.NewClusterInfo - 16MB 18.92% 56.75% 16MB 18.92% github.com/apache/yunikorn-core/pkg/rmproxy.NewRMProxy - 16MB 18.92% 75.67% 16MB 18.92% github.com/apache/yunikorn-core/pkg/scheduler.NewScheduler - 16MB 18.92% 94.59% 16MB 18.92% github.com/apache/yunikorn-k8shim/pkg/dispatcher.init.0.func1 - 1.04MB 1.23% 95.81% 1.04MB 1.23% k8s.io/apimachinery/pkg/runtime.(*Scheme).AddKnownTypeWithName - 0.52MB 0.61% 96.43% 0.52MB 0.61% github.com/gogo/protobuf/proto.RegisterType - 0.51MB 0.61% 97.04% 0.51MB 0.61% sync.(*Map).Store - 0.50MB 0.6% 97.63% 0.50MB 0.6% regexp.onePassCopy - 0.50MB 0.59% 98.23% 0.50MB 0.59% github.com/json-iterator/go.(*Iterator).ReadString - 0.50MB 0.59% 98.82% 0.50MB 0.59% text/template/parse.(*Tree).newText -``` - -您还可以运行 `web`、`pdf` 或 `gif` 命令来获取堆图形。 - -## 下载分析样本并在本地进行分析 - -我们在调度程序docker映像中包含了基本的go/go-tool二进制文件,您应该能够进行一些基本的分析 -docker容器内的分析。 但是,如果您想深入研究一些问题,最好进行分析 -本地。 然后您需要先将示例文件复制到本地环境。 复制文件的命令如下: - -``` -kubectl cp ${SCHEDULER_POD_NAME}:${SAMPLE_PATH_IN_DOCKER_CONTAINER} ${LOCAL_COPY_PATH} -``` - -例如 - -``` -kubectl cp yunikorn-scheduler-cf8f8dd8-6szh5:/root/pprof/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -在本地环境中获取文件后,您可以运行“pprof”命令进行分析。 - -``` -go tool pprof /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -## 资源 - -* pprof 文档 https://github.com/google/pprof/tree/master/doc。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/deployment_modes.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/deployment_modes.md deleted file mode 100644 index b33e1502aa1..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/deployment_modes.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -id: deployment_modes -title: 部署模式 ---- - - - -## YuniKorn部署模式 - -YuniKorn有两种部署模式: `标准模式`与`插件模式`。 -在标准模式下,YuniKorn作为自定义模式运行Kubernetes调度程序。 -在插件模式下,YuniKorn被实现为默认Kubernetes调度框架之上的一组插件。 - -在这两种情况下,建议同时运行准入控制器(admin controller),这会确保只有一个调度程序在您的Kubernetes集群中处于活动状态。 -当准入控制器运行时,所有pod将会绕过Kubernetes的默认调度器,除了YuniKorn本身的pod。 - -## 应该使用哪个版本? - -### 标准模式(Standard) - -目前的默认模式是标准模式。 标准模式提供稳定、高效、良好性能。 -当pod利用YuniKorn的队列功能,此模式非常适合大多数此类部署。 - -### 插件模式(Plugin) - -插件模式是一种新的部署模型,调度器是在默认的Kubernetes调度逻辑之上实现的,可以更好地兼容默认的Kubernetes调度器。 -它非常适合混合工作负载,如传统的Kubernetes以及排队的应用程序。 - -插件模式目前非常新,因此还没有达到标准模式的成熟度。 - -要在使用 Helm 部署时激活插件模式,请将变量`enableSchedulerPlugin`设置为`true`。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/gang_scheduling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/gang_scheduling.md deleted file mode 100644 index 8a27522b558..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/gang_scheduling.md +++ /dev/null @@ -1,296 +0,0 @@ ---- -id: gang_scheduling -title: Gang Scheduling ---- - - - -## What is Gang Scheduling - -When Gang Scheduling is enabled, YuniKorn schedules the app only when -the app’s minimal resource request can be satisfied. Otherwise, apps -will be waiting in the queue. Apps are queued in hierarchy queues, -with gang scheduling enabled, each resource queue is assigned with the -maximum number of applications running concurrently with min resource guaranteed. - -![Gang Scheduling](./../assets/gang_scheduling_intro.png) - -## Enable Gang Scheduling - -There is no cluster-wide configuration needed to enable Gang Scheduling. -The scheduler actively monitors the metadata of each app, if the app has included -a valid taskGroups definition, it will be considered as gang scheduling desired. - -:::info Task Group -A task group is a “gang” of tasks in an app, these tasks are having the same resource profile -and the same placement constraints. They are considered as homogeneous requests that can be -treated as the same kind in the scheduler. -::: - -### Prerequisite - -For the queues which runs gang scheduling enabled applications, the queue sorting policy should be set to `FIFO`. -To configure queue sorting policy, please refer to doc: [app sorting policies](user_guide/sorting_policies.md#application-sorting). - -#### Why the `FIFO` sorting policy - -When Gang Scheduling is enabled, the scheduler proactively reserves resources -for each application. If the queue sorting policy is not FIFO based (StateAware is FIFO based sorting policy), -the scheduler might reserve partial resources for each app and causing resource segmentation issues. - -#### Side effects of `StateAware` sorting policy - -We do not recommend using `StateAware`, even-though it is a FIFO based policy. A failure of the first pod or a long initialisation period of that pod could slow down the processing. -This is specifically an issue with Spark jobs when the driver performs a lot of pre-processing before requesting the executors. -The `StateAware` timeout in those cases would slow down processing to just one application per timeout. -This in effect will overrule the gang reservation and cause slowdowns and excessive resource usage. - -### App Configuration - -On Kubernetes, YuniKorn discovers apps by loading metadata from individual pod, the first pod of the app -is required to enclosed with a full copy of app metadata. If the app does not have any notion about the first or second pod, -then all pods are required to carry the same taskGroups info. Gang scheduling requires taskGroups definition, -which can be specified via pod annotations. The required fields are: - -| Annotation | Value | -|------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| yunikorn.apache.org/task-group-name | Task group name, it must be unique within the application | -| yunikorn.apache.org/task-groups | A list of task groups, each item contains all the info defined for the certain task group | -| yunikorn.apache.org/schedulingPolicyParameters | Optional. A arbitrary key value pairs to define scheduling policy parameters. Please read [schedulingPolicyParameters section](#scheduling-policy-parameters) | - -#### How many task groups needed? - -This depends on how many different types of pods this app requests from K8s. A task group is a “gang” of tasks in an app, -these tasks are having the same resource profile and the same placement constraints. They are considered as homogeneous -requests that can be treated as the same kind in the scheduler. Use Spark as an example, each job will need to have 2 task groups, -one for the driver pod and the other one for the executor pods. - -#### How to define task groups? - -The task group definition is a copy of the app’s real pod definition, values for fields like resources, node-selector, toleration -and affinity should be the same as the real pods. This is to ensure the scheduler can reserve resources with the -exact correct pod specification. - -#### Scheduling Policy Parameters - -Scheduling policy related configurable parameters. Apply the parameters in the following format in pod's annotation: - -```yaml -annotations: - yunikorn.apache.org/schedulingPolicyParameters: "PARAM1=VALUE1 PARAM2=VALUE2 ..." -``` - -Currently, the following parameters are supported: - -`placeholderTimeoutInSeconds` - -Default value: *15 minutes*. -This parameter defines the reservation timeout for how long the scheduler should wait until giving up allocating all the placeholders. -The timeout timer starts to tick when the scheduler *allocates the first placeholder pod*. This ensures if the scheduler -could not schedule all the placeholder pods, it will eventually give up after a certain amount of time. So that the resources can be -freed up and used by other apps. If non of the placeholders can be allocated, this timeout won't kick-in. To avoid the placeholder -pods stuck forever, please refer to [troubleshooting](troubleshooting.md#成组调度) for solutions. - -` gangSchedulingStyle` - -Valid values: *Soft*, *Hard* - -Default value: *Soft*. -This parameter defines the fallback mechanism if the app encounters gang issues due to placeholder pod allocation. -See more details in [Gang Scheduling styles](#gang-scheduling-styles) section - -More scheduling parameters will added in order to provide more flexibility while scheduling apps. - -#### Example - -The following example is a yaml file for a job. This job launches 2 pods and each pod sleeps 30 seconds. -The notable change in the pod spec is *spec.template.metadata.annotations*, where we defined `yunikorn.apache.org/task-group-name` -and `yunikorn.apache.org/task-groups`. - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-scheduling-job-example -spec: - completions: 2 - parallelism: 2 - template: - metadata: - labels: - app: sleep - applicationId: "gang-scheduling-job-example" - queue: root.sandbox - annotations: - yunikorn.apache.org/task-group-name: task-group-example - yunikorn.apache.org/task-groups: |- - [{ - "name": "task-group-example", - "minMember": 2, - "minResource": { - "cpu": "100m", - "memory": "50M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "50M" -``` - -When this job is submitted to Kubernetes, 2 pods will be created using the same template, and they all belong to one taskGroup: -*“task-group-example”*. YuniKorn will create 2 placeholder pods, each uses the resources specified in the taskGroup definition. -When all 2 placeholders are allocated, the scheduler will bind the the real 2 sleep pods using the spot reserved by the placeholders. - -You can add more than one taskGroups if necessary, each taskGroup is identified by the taskGroup name, -it is required to map each real pod with a pre-defined taskGroup by setting the taskGroup name. Note, -the task group name is only required to be unique within an application. - -### Enable Gang scheduling for Spark jobs - -Each Spark job runs 2 types of pods, driver and executor. Hence, we need to define 2 task groups for each job. -The annotations for the driver pod looks like: - -```yaml -Annotations: - yunikorn.apache.org/schedulingPolicyParameters: “placeholderTimeoutSeconds=30” - yunikorn.apache.org/taskGroupName: “spark-driver” - yunikorn.apache.org/taskGroup: “ - TaskGroups: [ - { - Name: “spark-driver”, - minMember: 1, - minResource: { - Cpu: 1, - Memory: 2Gi - }, - Node-selector: ..., - Tolerations: ..., - Affinity: ... - }, - { - Name: “spark-executor”, - minMember: 10, - minResource: { - Cpu: 1, - Memory: 2Gi - } - } - ] - ” -``` - -:::note -The TaskGroup resources must account for the memory overhead for Spark drivers and executors. -See the [Spark documentation](https://spark.apache.org/docs/latest/configuration.html#application-properties) for details on how to calculate the values. -::: - -For all the executor pods, - -```yaml -Annotations: - # the taskGroup name should match to the names - # defined in the taskGroups field - yunikorn.apache.org/taskGroupName: “spark-executor” -``` - -Once the job is submitted to the scheduler, the job won’t be scheduled immediately. -Instead, the scheduler will ensure it gets its minimal resources before actually starting the driver/executors. - -## Gang scheduling Styles - -There are 2 gang scheduling styles supported, Soft and Hard respectively. It can be configured per app-level to define how the app will behave in case the gang scheduling fails. - -- `Hard style`: when this style is used, we will have the initial behavior, more precisely if the application cannot be scheduled according to gang scheduling rules, and it times out, it will be marked as failed, without retrying to schedule it. -- `Soft style`: when the app cannot be gang scheduled, it will fall back to the normal scheduling, and the non-gang scheduling strategy will be used to achieve the best-effort scheduling. When this happens, the app transits to the Resuming state and all the remaining placeholder pods will be cleaned up. - -**Default style used**: `Soft` - -**Enable a specific style**: the style can be changed by setting in the application definition the ‘gangSchedulingStyle’ parameter to Soft or Hard. - -#### Example - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-app-timeout -spec: - completions: 4 - parallelism: 4 - template: - metadata: - labels: - app: sleep - applicationId: gang-app-timeout - queue: fifo - annotations: - yunikorn.apache.org/task-group-name: sched-style - yunikorn.apache.org/schedulingPolicyParameters: "placeholderTimeoutInSeconds=60 gangSchedulingStyle=Hard" - yunikorn.apache.org/task-groups: |- - [{ - "name": "sched-style", - "minMember": 4, - "minResource": { - "cpu": "1", - "memory": "1000M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - imagePullPolicy: "IfNotPresent" - command: ["sleep", "30"] - resources: - requests: - cpu: "1" - memory: "1000M" - -``` - -## Verify Configuration - -To verify if the configuration has been done completely and correctly, check the following things: -1. When an app is submitted, verify the expected number of placeholders are created by the scheduler. -If you define 2 task groups, 1 with minMember 1 and the other with minMember 5, that means we are expecting 6 placeholder -gets created once the job is submitted. -2. Verify the placeholder spec is correct. Each placeholder needs to have the same info as the real pod in the same taskGroup. -Check field including: namespace, pod resources, node-selector, toleration and affinity. -3. Verify the placeholders can be allocated on correct type of nodes, and verify the real pods are started by replacing the placeholder pods. - -## Troubleshooting - -Please see the troubleshooting doc when gang scheduling is enabled [here](troubleshooting.md#成组调度). diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/placement_rules.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/placement_rules.md deleted file mode 100644 index 17ccd279c87..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/placement_rules.md +++ /dev/null @@ -1,296 +0,0 @@ ---- -id: placement_rules -title: App 放置规则 ---- - - -基础的放置规则(placement rules)配置[调度弃配置设计文档](../design/scheduler_configuration#placement-rules-definition)中有相关描述。 - -我们可以将多个规则链结再一起形成一个放置策略,并通过[存取控制列表(Access control lists)](user_guide/acls.md)和规则过滤来定义和执行规则。 - -本篇文章将通过例子来解释如何建立策略以及规则的使用,而该放置策略为调度器的一部分。 - -## 配置 -放置规则作为调度程序队列配置的一部分,可以在各分区(partition)中被定义。规则定义的顺序就是他们会被执行的顺序。如果一个规则匹配,策略会停止执行剩余的规则。 - -匹配的放置规则会产生一个完全合格的队列名称。同时这个回传的队列名称会从根队列(root)开始。而在队列层次结构中,可以生成的层次数量没有限制。 - -当要执行一条规则时,已经被执行过的规则不会被列入考虑;这条规则也不会对往后要执行的规则有所影响:规则不能影响其他的规则,除非它们被配置为父规则([parent](#parent-参数))。 - -当放置策略没有生成队列名称且没有更多的规则时,应用程式将会被拒绝。 - -在配置中,定义放置规则的基本结构如下: -```yaml -placementrules: - - name: <第一条放置规则的名称> - - name: <第二条放置规则的名称> -``` -每个[规则](#规则)都可以在配置中采取一套预定义的参数。可以被使用的规则名称在规则描述中提及。规则名称在配置中不区分大小写,且必须遵从以下的命名惯例: -* 从字母开始:a-z 或 A-Z -* 后面跟着0或多个字元 a-z, A-Z, 0-9 或 _ - -当规则名称没有对应到任何已定义的规则时,表示规则处于未知的状态,会造成放置管理器初始化错误。如果参数不正确,会抛出解析错误或在初始化时发生错误。一个有错误的规则集永远不可能被激活。 - -如果放置管理器中含有一个被激活的规则集,就代表他已经初始化了。重新载入时,若配置了一个新的规则集时,就会将新的规则集激活,并取代旧有的。如果新规则集包含一个错误,放置管理器就会忽视这个新规则集,同时也持续处于「使用不完全的规则集」的状态。如果放置管理器持续使用已激活的规则集,忽视新的且有错误的规则集时,则会记录一条关于坏掉且被忽视的配置信息。 - -规则结果中的「点 "."」,会被文字的「"\_dot\_"」所替代。而「点」会被取代是因为在完全限定的队列名称中,他是被用来分隔队列层次的。而替代过程是发生在建构完整队列层次,且结果合格之前。这代表我们允许用「点」来表达用户名或标籤值,但不影响到队列层次。举例来说,当配置中的队列对应到「含有点的用户名」时,你必须要使用以下方法来指定它们:如果一个用户名称为`user.name`且使用`user`规则,则会产生队列名称为`root.user_dot_name`的队列。而如果该用户队列必须事先被加到配置中,则也该使用`user_dot_name`这个名字。 - -### Create 参数 -create 参数是一个布林值,会定义当一个队列不存在时,是否可以在规则的定义下创建队列。不能保证队列一定会被创建,因为现有的队列可能会阻止创建。但如果规则定义下想创建的队列不存在,且`create: false`,那结果将会是创建失败。 - -带有`create`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - create: true -``` -预设值为`false`。允许的值为`true`或`false`,其他值均会导致显示错误。 - -### Parent 参数 -`parent` 参数允许指定一个规则,并为他产生一个父队列。父规则可以被嵌套,一个父规则可以包含另一个父规则,此外对于父规则的嵌套也没有强制限制。 - -父规则被视为顶层的规则,因此具有与放置定义中任何其他规则相同的参数和需求。例外的情况是,在「已经生成完全合格队列」的规则上再使用父规则,被认为是一个配置错误。这个错误只能发生在`fixed`型的规则上,查看规范可以得到更多细节。 - -注意:规则的执行会沿着父规则的列表向下遍历,并首先执行列表中的最后一条。代表最后一条父规则将会直接产生在根部,详见示例。 - -带有`parent`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - parent: - name: <父规则的名称> -``` -预设值中没有parent参数。 - -### Filter 参数 -通过`filter`参数的定义,能过滤掉适用的用户来进行配置。过滤器是一个复杂的配置組件。 - -用户和群组可以被配置为两种类别: -* 正则表达式 -* 用户或群组的列表 - -如果用户或群组在yaml中的条目超过一个,则就会被视为一个用户列表或群组列表。列表中重复的条目会被忽略,不会引起错误。依据其他列表元素来使用正则表达式是不被允许的。 - -用户和群组名称遵循标准的Linux 用户和群组惯例,对于用户名来说: -* 从一个字母作为开头:a-z 或 A-Z -* 后面跟着0或更多个字符:a-z, A-Z, 0-9 或 _ . @ - -* 最后一个字符可以式$ - -对于群组名来说: -* 从一个字母作为开头:a-z 或 A-Z -* 后面跟着0或更多个字符:a-z, A-Z, 0-9 或 _ - - -如果列表中正好有一个条目,他可以是单个用户、群组或正则表达式。当一个条目包含一个在用户或群组中不允许的字符时,该条目会被认为是一个正则表达式。正则表达式必须按照规定进行编译。一个不能编译的正则表达式将会被忽略。 - -此外针对群组的正则表达式中:每次都是针对一个组进行匹配,而不是针对组的列表。 - -带有 `filter`参数的简易yaml范例: -```yaml -filter: - type: deny - users: - - - - - groups: - - - - -``` -预设值中没有filter参数。 - -### Value 参数 -这是一个通用值,用来传递给规则以实现或改变其行为。该值被用来与[fixed](#fixed-rule)和[tag](#tag-rule)型的规则一起使用。此外`value`是以字串型式存在的单一值,也不会被系统解释或干扰。 - -带有 `value`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - value: "any string" -``` -预设值中没有value参数。 - -## 准入控制列表 -准入控制列表没有在规则中定义,但它们影响放置策略的结果。有两种准入控制列表可以被定义到队列上: -1. 提交ACL: `submitacl` -2. 管理ACL: `adminacl` - -如果队列的ACL允许任何ACL提交存取,则放置规则才能匹配。管理队列ACL还提供「提交准入」的功能。如果队列不存在或没有配置ACL,则将检查父队列的ACL。这种递迴的检查会重复执行,直到有ACL提供存取或根目录的ACL被检查过后。 - -关于ACL语法的更多细节,请查阅[ACL文档](user_guide/acls.md)。 - -## 规则 -### Provided Rule -在配置中使用的名称:*provided* - -提供在提交应用时所指定的队列。本规则的行为是─如果队列不完全合格,则完全限定由「应用程序提供的队列」作为放置的队列。如果设置了一个父规则,并且在应用程序提交中提供的队列是完全合格的,那麽父规则就不会被执行。 - -支持的参数: -* create -* parent -* filter - -举例:如果用户名下不存在队列,则用户传入的队列会被创建。 -```yaml -placementrules: - - name: provided - create: true - parent: - name: user - create: true -``` -当用户 `developer` 向应用程式提交请求,且应用程式要求的队列名称为:`my_special_queue`。
-结果:`root.developer.my_special_queue`(父规则将设置用户名称)。 - -当用户 `developer` 向应用程式提交请求,且应用程式要求的队列名称为:`root.dev_queue`。
-结果:`root.dev_queue`(父规则将被忽视)。 - -### User Name Rule -在配置中使用的名称:*user* - -提供一个基于用户名的队列,而该用户名为所提交的应用程序的一部分。 - -支持的参数: -* create -* parent -* filter - -举例:提交一个基于用户名的队列,如果队列不存在,不要创建队列。 -```yaml -placementrules: - - name: user - create: false -``` - -当用户`finance.test`提交了一个应用程式,此外对应的队列也存在。
-结果: `root.finance_dot_test`(注意,「点」被替换了)。 - -当用户`developer`提交了一个应用程式,但对映的队列不存在。
-结果:失败,执行下一条规则。 - -### Fixed Rule -在配置中使用的名称:*fixed* - -回传一个队列,其依据规则参数的值作为名称,配置的值必须是一个合法的队列名称或层次结构。该队列名称不一定需要完全合格。名称中的层次结构使用「一个点(.)」作为层次结构中不同级别的分隔符。只有当配置的队列不存在且`create`标籤未设置时,`fixed`规则才会失败,因为他始终新增一个配置的队列。 - -支持的参数: -* value(reuqired) -* create -* parent -* filter - -举例:因为总是会回传一个队列,若没有设置`create`标籤,则要在配置中将队列定义为子队列。 -```yaml -placementrules: - - name: fixed - value: last_resort -``` - -当用户 `developer`提交请求,且在应用程式中设定的队列为:`my_special_queue` 。
-结果:`root.last_resort`。 - -### Tag Rule -在配置中使用的名称:*tag* - -从应用程式的标籤中检索队列名称。检查`tag`的值(value),并在规则中使用该值进行配置。若`tag`规则没有包含任何值,则代表配置错误,但是一个应用程式不一定要设置该值。 - -如果应用程序上没有设置对应的`tag`,则规则失败。如果从应用程序回传的`tag` value是一个完全限定的队列名称,则父规则(如果已配置)将不会执行。 - -支持的参数: -* value(reuqired) -* create -* parent -* filter - -举例:根据kubernetes命名空间放置一个应用程序,该命名空间在提交时自动在应用程序中设置。 -```yaml -placementrules: - - name: tag - value: namespace - create: true -``` - -用户`developer`在命名空间`default`,提交基于kubernetes的应用程序请求,且在应用程是中设定的队列为:`my_pecial_queue`。
-结果:`root.default`。 - -用户`developer`在命名空间`testing`,提交基于kubernetes的应用程序请求,且在应用程是中设定的队列为:`my_pecial_queue`。
-结果:`root.testing`。 - -用户提交非基于kubernetes的应用程序请求。
-结果:失败,执行下一条规则。 - -## 复杂的例子 -在这个复杂的例子中,我们串连了三个规则: - -1. 一个`user`规则,其父规则标籤使用kubernetes命名空间,且仅供`dev`群组内的用户。 -2. 一个`tag`规则,使用kubernetes命名空间,其`parent`规则固定使用已存在的队列─ `root.namespaces`。 -3. 一个`fixed`规则,将所有到达这个点的应用程序都放在`root.default`队列中。 - -举例: -```yaml -placementrules: - - name: user - create: true - filter: - type: allow - groups: - - dev* - parent: - - name: tag - value: namespace - - name: tag - value: namespace - create: true - parent: - - name: fixed - value: root.namespaces - filter: - type: allow - users: - - john - - name: fixed - value: root.default -``` -用户`john`在命名空间testing中提交基于kubernetes应用程序的请求。
-结果:`root.namespaces.testing`(在规则2中匹配)。 - -用户`sarah`在命名空间`newapp`中提交基于kubernetes应用程序的请求,组员为`sarah`, `test_app`, `dev_app`。
-结果:`root.newapp.sarah`(在规则1中匹配)。 - -用户bob在命名空间`testapp`中提交基于kubernetes应用程序的请求,组别成员为`bob`。
-结果:`root.default`(在规则3中匹配)。 -
-在第二个例子中,我们使用了两条规则。 - -1. 一个`fixed`规则,将所有东西放在`root.production`队列中。 -2. 一个`user`规则,以及设置 `create` 标籤。 - -但在这个例子中,我们在`root.production`的队列上设置了ACL,只允许两个特定的用户使用这个队列。因此,即使规则匹配,除非是`john`或`bob`,否则应用程式将不会被放在`production`队列中。所有其他用户将匹配第二条规则并使用它们自己的队列,如果队列不存在,就会创建。 - -```yaml -partitions: - - name: default - queues: - - name: production - submitacl: john,bob - placementrules: - - name: fixed - value: root.production - - name: user - create: true -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/queue_config.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/queue_config.md deleted file mode 100644 index c8a140eba35..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/queue_config.md +++ /dev/null @@ -1,382 +0,0 @@ ---- -id: queue_config -title: 分区和队列配置 ---- - - - -队列配置基础在[配置设计文档](design/scheduler_configuration.md)中有描述。 - -本文档提供通用队列配置。 -队列配置引用了[访问控制列表](user_guide/acls.md)和[放置规则](user_guide/placement_rules.md)文档。 - -本文档通过示例说明如何为调度程序创建分区和队列配置。 - -调度程序依靠shim可靠地提供用户信息作为应用程序提交的一部分。 -当前shim使用[用户和组解析](usergroup_resolution)中提供的方法识别用户和用户所属的组。 - -## 配置 -此处描述的调度器的配置文件仅提供分区和队列的配置。 - -默认情况下,我们在部署中使用`queues.yaml`文件。 -文件名可以通过命令行更改调度器的`policyGroup`标志。 -更改文件名后必须对部署细节进行相应的更改,可以是`configmap`或包含在docker容器中的文件。 -配置的示例文件位于yunikorn-core的[queues.yaml](https://github.com/apache/yunikorn-core/blob/master/config/queues.yaml). - -## 分区 -分区(partitions)是调度器配置的最高级别。 -在配置中可以定义多个分区。 - -配置中分区定义的基本结构如下: -```yaml -partitions: - - name: <第一个分区的名称> - - name: <第二个分区的名称> -``` -分区的默认名称是`default`。 -分区定义包含特定shim相应调度器的完整配置。 -每个shim都使用自己独特的分区。 - -分区必须至少需要定义以下键: -* name -* [queues](#队列) - -队列配置会在分区结束后介绍。 - -可以选择为分区定义以下键: -* [placementrules](#放置规则) -* [statedumpfilepath](#状态转储文件路径) -* [limits](#限制) -* nodesortpolicy -* preemption - -放置规则和限制在各自的章节中解释。 - -`nodesortpolicy`定义节点为分区排序的方式。 -有关可以使用的节点排序策略值的详细信息,请参阅[排序策略](user_guide/sorting_policies.md#node-sorting)文档。 - -抢占键目前只能有一个子键: _enabled_。 -这个布林值定义了整个分区的抢占行为。 - -_enabled_的默认值为_false_。 -_enabled_的允许值:_true_或_false_,任何其他值都会导致解析错误。 - -下方的示例中,`partition` yaml条目是带有_preemption_标志集和_fair_的`nodesortpolicy`。 -```yaml -partitions: - - name: <分区名称> - nodesortpolicy: fair - preemption: - enabled: true -``` -备注: -目前,Kubernetes独特的shim不支持除`default`分区之外的任何其他分区。 -这已被记录为shim的[jira](https://issues.apache.org/jira/browse/YUNIKORN-22)。 - -### 队列 - -YuniKorn通过利用资源队列来管理资源。 -资源队列(queues)具有以下特征: -- 队列可以有**层次**结构 -- 每个队列都可以预设**最小/最大容量**,其中最小容量定义保证资源,最大容量定义资源限制(所谓的资源配额) -- 任务必须在某个`leaf`队列下运行 -- 队列可以是**静态**(从配置文件加载)或**动态**(由YuniKorn内部管理) -- 队列级别的**资源公平**是由调度器强制执行 -- 作业只能在特定队列下运行 - -:::info -YuniKorn队列与[Kubernetes命名空间](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)的区别: -Kubernetes命名空间提供了Kubernetes资源的范围,包括安全环境(即谁可以访问对象),以及定义[资源配额](https://kubernetes.io/docs/concepts/policy/resource-quotas/)时的资源边界(即对象可以使用多少资源)。 -另一方面,YuniKorn队列仅使用一组作业可以使用多少资源,以及以何种顺序使用。 -YuniKorn队列在考虑资源公平性、作业排序等方面提供了更细粒度的多租户资源共享控制。 -在大多数情况下,YuniKorn队列可用于替代命名空间资源配额,以提供更多的调度特性。 -::: - -_queues_条目是主要的配置元素,它为队列定义了层次结构。 - -它可以定义一个`root`队列,但它不是必需的元素。 -如果未定义`root`队列,配置解析将插入root队列以保持一致性。 -以下因素会触发root队列的插入: -* 如果配置在顶层定义了多个队列,则会插入一个根队列。 -* 如果在顶层只定义了一个队列并且它不被称为`root`,则插入一个root队列。 - -定义的一个或多个队列将成为插入的`root`队列的子队列。 - -带有子队列的基本`queue` yaml条目: -```yaml -queues: -- name: <队列名称> - queues: - - name: <队列名称> -``` - -队列支持的参数: -* name -* parent -* queues -* maxapplications -* properties -* adminacl -* submitacl -* [resources](#资源) -* [limits](#限制) - -每个队列都必须有一个_name_并且队列的名称在定义队列的同一级别上必须是唯一的。 -由于队列结构是完全层次化的,层次结构中不同点的队列可能具有相同的名称。 -例如:队列结构`root.testqueue`和`root.parent.testqueue`是一个有效的结构。 -需注意的是,队列不能包含点“.”字符,因为该字符用于分隔层次结构中的队列。 -如果名称对于配置中的队列不是唯一的,或者名称包含一个点,则会生成解析错误并拒绝配置。 - -依队列的类型是否于队列有子模板队列和子队列的事实,结构中的队列将自动获得分配的类型。 -队列类型有两种: -* parent -* leaf - -应用只能分配给_leaf_队列。 -在配置中,队列具有子模板队列或子队列将自动成为_parent_队列。 -如果队列在配置中没有子队列,则该队列是_leaf_队列,除非该队列`parent`参数设置为_true_。 -尝试覆盖配置中的_parent_队列类型将导致配置解析错误。 - -parent队列的子队列在`queues`条目下定义。 -`queues`条目是队列级别的递归条目,它使用完全相同的参数集。 -_maxapplications_属性是一个大于 1 的整数值,它允许您限制队列中正在运行的应用的数量。 -不允许为_maxapplications_指定零,因为它会阻止队列中应用的任何分配。 -_子_队列的_maxapplications_值必须小于或等于_parent_队列的值。 -`properties`参数是一个简单的键值对列表,并为队列提供一组简单的属性。其中的键或值没有限制,任何东西都是允许的。 -目前,属性列表仅在调度器中用于定义leaf队列的[排序顺序](user_guide/sorting_policies.md#application-sorting)。 -在未来的扩展中,添加比如打开或关闭队列抢占或其他排序策略的选项,让使用相同的属性构造而无需更改配置。 - -通过`adminacl`设置对队列的访问权限以进行管理操作,并通过`submitacl`条目提交应用。 -访问控制列表(ACLs)的描述可见[访问控制列表(ACLs)](user_guide/acls.md)文档。 - -队列资源限制是通过`resources`参数设置。 -用户和群组的限制是通过`limits`参数设置。 -由于这两个条目都是复杂的配置条目,因此它们在下面的[resources](#资源)和[limits](#限制)中有相应解释。 - -以下示例配置是`root.namespaces`队列作为具有限制的_parent_队列: -```yaml -partitions: - - name: default - queues: - - name: namespaces - parent: true - maxapplications: 12 - resources: - guaranteed: - {memory: 1G, vcore: 10} - max: - {memory: 10G, vcore: 100} - queues: - - name: level1 - maxapplications: 8 - resources: - guaranteed: - {memory: 0.5G, vcore: 5} - max: - {memory: 5G, vcore: 50} -``` - -### 放置规则 - -放置规则(placement rules)在[放置规则](user_guide/placement_rules.md)文档中有相关定义和记录。 - -每个分区只能定义一组放置规则。 -如果没有定义规则,则放置管理器不会启动。 -此外,在提交应用时,*必须*为每个应用设置一个队列。 - -### 状态转储文件路径 - -状态转储文件路径(Statedump filepath)定义YuniKorn状态转储的输出文件并且它可以在分区级别上设置。 -如果设置转储文件路径,该字段的值可以是相对路径或绝对路径(此处相对路径是基于工作目录)。 -如果YuniKorn调度器没有足够的权限在指定路径创建状态转储文件,它将无法启动状态转储的功能。 - -```yaml -statedumpfilepath: -``` -如果上面的键没有在分区配置中指定,它的默认值为`yunikorn-state.txt`。 -需注意的是,如果键在多个分区中指定,则其第一次出现的值优先。 - -状态转储文件也有一个固定的循环策略。 -目前,每个状态转储文件的容量为10MB,最多可以有10个这样的文件。 -当前正在写入的状态转储文件将始终是上面配置的值或默认的`yunikorn-state.txt`。 -当达到文件大小限制时,日志旋转器(`lumberjack`)将通过在文件前加上时间戳来修改文件,并创建一个具有相同的无前缀名称的新文件来写入状态转储。 -如果达到状态转储文件的最大数量,轮换策略将删除根据标记时间戳的最旧文件。 - -### 限制 -限制(limits)为分区或队列定义一组限制对象,以及它可以在分区或任何级别的队列上设置。 -```yaml -limits: - - limit: <描述> - - limit: <描述> -``` - -限制对象是一个复杂的配置对象,它为一组用户和/或群组定义一个限制。 -多个独立的限制可以设置为队列或分区上一个`limits`条目的一部分。 -不属于限制设置的用户和/或群组将不受限制。 - -limits条目的示例: -```yaml -limits: - - limit: <描述> - users: - - <用户名或"*"> - - <用户名> - groups: - - <群组名称或"*"> - - <群组名称> - maxapplications: <1..最大值> - maxresources: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] -``` - -队列限制的情况下,应用递归限制。 -这意味着对`root`队列的限制是集群中用户或群组的总体限制。 -因此,`root`队列限制也等同于`partition`限制。 - -limits参数: -* limit -* users -* groups -* maxapplications -* maxresources - -_limit_参数是limits条目的可选描述。 -除了使配置易于理解和可读之外,它不用于任何其他用途。 - -可以配置的_users_和_groups_可以是以下两种类型之一: -* 一个星号字符 "*" -* users或groups的列表。 - -如果users或groups的条目包含超过1个条目,则它始终被视为users或groups的列表。 -星号字符“*”为通配符,匹配所有用户或群组。 -不允许在其他列表元素旁边指定星号字符。 -列表中的重复条目将被忽略,并不会导致解析错误。 - -_maxapplications_是一个无符号整数值。 -当_maxapplications_大于1,它允许您限制为配置的用户或群组运行的应用的数量。 -不允许指定_maxapplications_为0,因为_maxapplications_为0时,隐含拒绝任何访问。 -拒绝访问的规范应交由ACL条目处理。 - -_maxresources_参数可用于指定一个或多个资源的限制。 -_maxresources_使用与队列的[resources](#资源)参数相同的语法。 -未在列表中指定的资源不受限制。 -资源限制可以设置为 0,这可以防止用户或群组请求指定的资源,即使队列或分区具有可用的特定资源也是如此。 -不允许将总体资源限制指定为零,换言之,这意味着限制中指定的至少一个资源必须大于零。 -如果资源在队列上不可用,则应使用队列定义上的最大资源。 -指定一个实际上为零的限制,_maxapplications_ 为零并且所有资源限制为零,这是不允许的,并且会导致解析错误。 - -每个用户或群组都有一个限制,它*不是*所有用户或群组的组合限制。 - -举个例子: -```yaml -limit: "example entry" -maxapplications: 10 -users: -- sue -- bob -``` -在这种情况下,用户`sue`和`bob`都被允许运行10个应用。 - -### 资源 -队列的resources条目可以为队列设置_guaranteed_和/或_maximum_资源,yunikorn会递归地检查资源限制。 -leaf队列的资源使用量是为该队列分配的所有资源的总和。 -parent队列的资源使用量是该parent队列下面所有队列,leaf和parent队列的资源使用量的总和。 - -root队列没有_guaranteed_的资源设置。 -root队列的_max_资源限制自动等于集群大小。 -如果root队列设置了任何限制,则会发生解析错误。 -leaf队列在定义时不能设置任何资源限制。 - -配置后的_max_资源对可以在任何时间点分配给队列的所有分配的大小进行了硬性限制。 -_max_资源可以设置为0,这使得资源对队列不可用。 -_guaranteed_资源用于计算队列份额和分配期间,它用作决定将分配分配给哪个队列的输入之一。 -抢占使用队列的_guaranteed_资源作为队列不能低于的基础。 - -基本的`resources` yaml条目: -```yaml -resources: - guaranteed: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] - max: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] -``` -列表中未指定的资源不受限制,对于最大(max)资源,或在保证(guaranteed)资源的情况下保证。 - -可以为资源数量指定一个可选的后缀。 -有效的国际单位制后缀是`k`、`M`、`G`、`T`、`P` 和 `E`,用于10的幂,以及`Ki`、`Mi`、`Gi`、`Ti`、 `Pi`和`Ei`表示2的幂。 -此外,`vcore`类型的资源可能带有后缀`m`以表示millicores。 例如,`500m`是vcore的50%。 -默认情况下,`memory`类型的单位以byte为单位进行解释。 -所有其他资源类型都没有指定的基本单位。 - -注意,以上单位行为从yunikorn 1.0开始有效 -以前的版本将`memory`解释为1000000(百万)bytes的单位,将`vcore`解释为millicores。 - -### 子模板 - -子模板(child template)可以在父类型队列的队列层次结构中的任何级别来定义。 -parent队列可以提供一个模板来定义它下面的动态leaf队列的行为。 -如果parent队列定义了子模板,则没有子模板的parent队列会从其parent队列继承子模板。 - -模板中支持的配置如下所示。 -1. application sort policy -2. max resources -3. guaranteed resources -4. max applications - -举个例子: -```yaml - partitions: - - name: default - placementrules: - - name: provided - create: true - queues: - - name: root - submitacl: '*' - childtemplate: - maxapplications: 10 - properties: - application.sort.policy: stateaware - resources: - guaranteed: - vcore: 1 - memory: 1G - max: - vcore: 20 - memory: 600G - queues: - - name: parent - parent: true - childtemplate: - resources: - max: - vcore: 21 - memory: 610G - - name: notemplate - parent: true -``` -在这种情况下,`root.parent.sales`将直接使用parent队列`root.parent`的子模板。 -相比之下,`root.notemplate.sales`将使用在队列`root`上设置的子模板,因为其parent队列 `root.notemplate` 从队列`root`继承了子模板。 - -[已弃用] 如果您的集群依赖于动态叶队列可以从父级继承`application.sort.policy`的旧行为(由[YUNIKORN-195](https://issues.apache.org/jira/browse/YUNIKORN-195)引入),请迁移到模板。 -旧的行为将在未来的版本中被删除。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/troubleshooting.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/troubleshooting.md deleted file mode 100644 index 4b47d6b0ab4..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/troubleshooting.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -id: troubleshooting -title: 故障排除 ---- - - - -## 调度日志(Scheduler logs) - -### 检索调度日志 - -调度器会将日志写入stdout/stderr,docker容器就会将这些日志重新导向到节点的本地位置,你可以从[这里](https://docs.docker.com/config/containers/logging/configure/)读到更多的文档,这些日志可以通过[kuberctl logs](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs)检索。如: - -```shell script -//获取调度的pod -kubectl get pod -l component=yunikorn-scheduler -n yunikorn -NAME READY STATUS RESTARTS AGE -yunikorn-scheduler-766d7d6cdd-44b82 2/2 Running 0 33h - -//检索日志 -kubectl logs yunikorn-scheduler-766d7d6cdd-44b82 yunikorn-scheduler-k8s -n yunikorn -``` - -在大多数的情况下,这个命令没有办法获取所有的日志,因为调度程序的日志数量庞大,您需要设置[集群级别的日志收集](https://kubernetes.io/docs/concepts/cluster-administration/logging/#cluster-level-logging-architectures)。推荐的设置方式是利用[fluentd](https://www.fluentd.org/)在外部储存(例如s3)上持久的收集日志。 - -### 设定日志级别 - -### -:::note -我们建议通过REST API来调整日志级别,如此以来我们不需要每次修改级别时重新启动调动程序的pod。但是透过编辑部署配置来设定日志级别时,需要重新启用调度程序的pod,因此强烈不建议这么做。 -::: - -停止调度器: -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -``` - -使用vim编辑部署配置: -```shell script -kubectl edit deployment yunikorn-scheduler -n yunikorn -``` - -在容器模板的`env`字段中加入`LOG_LEVEL`。例如将`LOG_LEVEL`设置为0会将日志纪录的级别设置为`INFO`。 - -```yaml -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: -… -spec: -template: -… -spec: -containers: -- env: -- name: LOG_LEVEL -value: '0' -``` - -启用调度器: -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -可使用的日志级别: - -| 值 | 日志级别 | -|:-----: |:-------------: | -| -1 | DEBUG | -| 0 | INFO | -| 1 | WARN | -| 2 | ERROR | -| 3 | DPanic | -| 4 | Panic | -| 5 | Fatal | - -## Pods卡在`Pending`状态 - -如果Pod卡在Pending状态,则意味着调度程序找不到分配Pod的节点。造成这种情况有以下几种可能: - -### 1.没有节点满足pod的放置要求 - -可以在Pod中配置一些放置限制,例如[节点选择器(node-selector)](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)、[亲合/反亲合性(affinity/anti-affinity)](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)、对节点的[污点(taints)](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)没有一定的容忍度等。若要修正此类问题,你可以通过以下方法观察pod: - -```shell script -kubectl describe pod -n <命名空间> -``` - -pod事件中包含预测失败,而这解释了为什么节点不符合分配条件 - -### 2.队列的可用资源不足 - -如果队列的可用资源不足,Pod将等待队列资源。检查队列是否还有空间可以给Pending pod的方法有以下几种: - -1 ) 从Yunikorn UI检查队列使用情况 - -如果你不知道如何访问UI,可以参考[这里](../get_started/get_started.md#访问-web-ui)的文档。在`Queues`页面中,寻找Pod对应到的队列。你将能够看到队列中剩馀的可用资源。 - -2 ) 检查pod事件 - -运行`kubectl describe pod`以获取pod事件。如果你看到类似以下的事件:`Application does not fit into <队列路径> queue`。则代表pod无法分配,因为队列的资源用完了。 - -当队列中的其他Pod完成工作或被删除时,代表目前Pending的pod能得到分配,如果Pod依旧在有足够的剩馀资源下,保持pending状态,则可能是因为他正在等待集群扩展。 - -## 获取完整的状态 - -Yunikorn状态储存中,包含了对每个进程中每个对象的状态。透过端点来检索,我们可以有很多有用的信息,举一个故障排除的例子:分区列表、应用程序列表(包括正在运行的、已完成的以及历史应用程序的详细信息)、节点数量、节点利用率、通用集群信息、集群利用率的详细信息、容器历史纪录和队列信息。 - -状态是Yunikorn提供的用于故障排除的宝贵资源。 - -有几种方法可以获得完整的状态: -### 1.调度器URL - -步骤: -*在浏览器中打开Yunikorn UI,且在URL中编辑: -*将`/#/dashboard`取代为`/ws/v1/fullstatedump`,(例如,`http://localhost:9889/ws/v1/fullstatedump`) -*按下回车键。 - -透过这个简单的方法来观看即时且完整的状态。 - -### 2.调度器的REST API - -使用以下的调度器REST API,能够让我们看到Yunikorn的完整状态。 - -`curl -X 'GET'http://localhost:9889/ws/v1/fullstatedump-H 'accept: application/json'` - -有关储存状态的更多信息,可以参阅[检索完整状态](api/scheduler.md#retrieve-full-state-dump)的文档。 - -## 重启调度器 -:::note -最好的故障排除方法是─把「重启调度器」当作完全没有其他方法之下的最后一步,他不应该在搜集所有日志和状态之前使用。 -::: - -Yunikorn可以在重启之后恢复其状态。Yunikorn调度器的pod作为deployment部署。我们可以透过`scale`来增加和减少副本数量来重启Yunikorn调度器,方法如下: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -## 成组调度 -### 1.没有占位符被创建,且app处于pending状态 -*原因*:这通常是因为应用程序被调度气拒绝,因此没有一个pod被调度。 - -导致拒绝的常见原因有: - -1)任务群组(taskGroups)定义无效。调度程序在应用程序被提交时会进行健全性检查,以确保正确定义所有任务群组,如果这些信息的格式不正确,调度程序将拒绝该应用程序 - -2)任务群组中定义的总最小资源量大于队列的最大资源量,因此调度程序拒绝该应用程序,因为队列的资源量无法满足它。可以通过检查pod事件中的相关消息,或调度器日志来找到更多详细的错误信息。 - -*解决方案*:更正任务群组的定义并重新提交应用程序。 - -### 2.有些占位符没有被分配 -*原因*:占位符也会消耗资源,如果不能全部分配,通常是队列或者集群没有足够的资源分配给它们。在这种情况下,占位符将在一定时间后被清理,该时间由调度策略参数─`placeholderTimeoutInSeconds`所定义。 - -*解决方案*:如果占位符超时了,目前的app将会转为failed状态,无法再被调度。如果您愿意等待更长的时间,可以增加占位符超时的值。将来可能会添加倒退策略以提供重试,而不是使应用程序失败。 - -### 3.有些占位符没有被交换 -*原因*:这通常代表应用程序的pod少于任务群组中定义的最小成员数(`minMembers`) - -*解决方案*:检查任务群组字段中的`minMember`并确保其设置正确。`minMember`可以小于实际的pod数,设置大于实际pod数是无效的。 - -### 4.应用程序终止时不会清除占位符 -*原因*:所有占位符都会设置[ownerReference](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents)到应用程序的第一个真实的pod,或控制器参考。如果无法清理占位符,则意味着垃圾回收(garbage collector)的机制不正常。 - -*解决方案*:检查占位符的`ownerReference`和Kubernetes中的垃圾收集器。 - -## 仍然遇到问题? -没问题!Apache Yunikorn社区将很乐意提供帮助。您可以通过以下选项联系社区: - -1. 将您的问题发布到dev@yunikorn.apache.org。 -2. 加入[YuniKorn slack](https://join.slack.com/t/yunikornworkspace/shared_invite/enQtNzAzMjY0OTI4MjYzLTBmMDdkYTAwNDMwNTE3NWVjZWE1OTczMWE4NDI2Yzg3MmEyZjUyYTZlMDE5M2U4ZjZhNmYyNGFmYjY4ZGYyMGE)并将您的问题发布到`#yunikorn-user`频道。 -3. 加入[社区会议](http://yunikorn.apache.org/community/get_involved#community-meetings)并直接与社区成员交谈。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/usergroup_resolution.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/usergroup_resolution.md deleted file mode 100644 index 7702498cd21..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/usergroup_resolution.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -id: usergroup_resolution -title: 解析用户和群组 ---- - - - -## 用户解析 (User resolution) - -用户信息是调度周期的重要概念,他是決定「是否将作业提交到队列」的关键指标之一。Yunikorn调度器依赖k8s Shim来提供用户信息,但在Kubernetes的世界中,没有任何对象可以识别实际用户,这是基于设计使然,可以从这个[页面](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#users-in-kubernetes)中得到更多资讯。 - -在Yunikorn中有两种处理用户和群组的方法。第一种是传统的方式,使用标签`yunikorn.apache.org/usernname`。如果此标签设置在pod上,则该值会自动提取到shim中并被使用。群组解析也在shim中完成,但预设是不启用的。这种方法的问题有两个方面:首先,用户限制可以很容易地被绕过,因为提交者可以自由地将标签设置为任何值,因此这只能在受信任的环境中使用。其次,在shim中识别组别太慢了─将用户分配到多个群组​是不可行的,因为根据身份验证机制(如X509,tokens,LDP,etc)可能很难查找用户属于哪一个群组。 - -由于这些限制很大,为了向后兼容才保留了此方法,且将来可能会被删除。 - -一种更可靠和健全的机制是使用`yunikorn.apache.org/user.info`,其中用户信息中的「允许的用户或群组列表」可以由从外部设置,或者准入控制(admission controller)可以自动将其附加到每个工作负载(workflow)。 - -## 传统的用户处理 - -### 使用`yunikorn.apache.org/username`标签 - -由于kubernetes没有预定义的字段和资源能用于用户信息,且个别集群使用的用户识别工具可能有所不同,于是我们定义了标准的方法来识别用户。Yunikorn需要添加一个kubernetes[标签](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)。这里提供了[推荐的使用方法](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/),预设的标签定义如下: - -|标签|值| -|----------------------------------------------- |--------------------- | -| yunikorn.apache.org/username |用户名。可以重复该条目,但只会使用第一个值。默认的用户是`nobody` | - -举例: -```yaml -metadata: - labels: - yunikorn.apache.org/username:"john" -``` -:::tip -为了让该字段(field)成为唯一识别用户的指标,建议集群管理员使用用户识别工具,将这个标签设为不可变的字段。集群管理员或用户可以自由的使用任何方法或工具来增加这个字段和值。其中包含在提交时手动添加。 -::: - -:::note 假设 -假设: -Yunikorn假设一个应用程序的所有pod都属于同一个用户。我们建议将用户标签添加到应用程序的每个pod。这是为了确保没有任何意外。 -::: - -在[K8s的部署](https://github.com/apache/yunikorn-release/blob/master/helm-charts/yunikorn/templates/deployment.yaml)时,可以通过覆盖`USER_LABEL_KEY`来改变标签`yunikorn.apache.org/username`的默认值,这在已经添加用户标签,或出于某些安全因素下必须修改标签的情况下特别有用。 - -```yaml - env: - - name: USER_LABEL_KEY - value:"custom_user_label" -``` - -### 群组解析 (Group resolution) - -这里包含群组成员解析的定义,此外该功能是可以选择加入或移除的。群组不必是用户或群组对象所提供的一部分。当对象被加到缓存中时,群组将自动根据配置来解析。可以为每个分区(partition)设置连接到缓存的解析器(resolver)。 - -预设的群组解析器是"no resolver"。此解析器仅回传用户明和与用户同名的主要群组。 - -其他解析器: -* 操作系统解析器 -* 测试解析器 - -## 推荐的处理用户的新方式 - -从Yunikorn 1.2开始,可以使用更复杂的用户/群组解析方式。 - -在这种模式下,Yunikorn不再依赖标签`yunikorn.apache.org/username`,而是将`yunikorn.apache.org/user.info`附加到工作负载。通过简单的JSON值,定义用户名和群组: - -```yaml -metadata: - annotations: - yunikorn.apache.org/user.info:" - { - username: \"yunikorn\", - groups: [ - \"developers\", - \"devops\" - ] - }" -``` - -然而,为了加强安全性,在准入控制器中强制执行了以下操作: -* 不是集群中的每个用户都可以附加此注解(annotation),只有在配置允许时才可以使用。 -* 如果缺少注解,则准入控制器将自动添加。 -* 若尝试修改此注解将会被拒绝。 - -我们不只在pods上这样做,而是在Deployments,ReplicaSet,DeamonSet,StatefulSet,Jobs和CronJobs上都这样做。 - -此外,群组解析器不再需要放在k8s-shim中。 - -### 配置准入控制器 - -准入控制可以在`yunikorn-configs`的configmap中被配置。所有条目都以前缀`admissionController.accessControl.`开头。 - -|变量|默认值|描述| -|--|--|--| -|`bypassAuth`|false|允许任何外部用户使用用户信息集创建pod| -|`trustControllers`|true|允许Kubernetes控制器的用户创建带有用户信息集的pod| -|`systemUsers`|"^system:serviceaccount:kube-system:"|允许控制器符物帐号列表使用正则表达式| -|`externalUsers`|""|在「允许的外部用户列表」上使用正则表达式| -|`externalGroups`|""|在「允许的外部群组列表」上使用正则表达式| - -如果`bypassAuth`设置为`true`,但注解不存在且设定了已遗弃的用户标签,则准入控制器将不会把注解加到pod中。如果未设置注解也未设置用户标签,则新的注解将会被加入。 -在`bypassAuth`为`false`(默认值)的情况下,准入控制器将始终添加新的注解,而不管是否存在已弃用的标签。 - -在某些情况下,必须将用户和群组在提交时提供给Yunikorn,因为用户和群组管理由外部系统提供,查找机制并不简单。因此,在这些情况下,可以将`externalUsers`和`externalGroups`配置为正则表达式。其中,匹配的用户或群组就可以将`yunikorn.apache.org/user.info`设置为任意值。但这会影响Yunikorn内部的调度,因此必须仔细设置这些属性。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_flink.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_flink.md deleted file mode 100644 index 40eb05b1978..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_flink.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: run_flink -title: 运行Flink作业 -description: 如何与YuniKorn一起运行Flink作业 -image: https://svn.apache.org/repos/asf/flink/site/img/logo/png/100/flink_squirrel_100_color.png -keywords: - - spark ---- - - - -使用 YuniKorn 在 Kubernetes 上运行 [Apache Flink](https://flink.apache.org/) 非常容易。 -根据在 Kubernetes 上运行 Flink 的模式不同,配置会略有不同。 - -## Standalone(独立)模式 - -请关注 [Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/kubernetes.html) 以获取 standalone 部署模式的细节和示例。 -在这种模式下,我们可以直接在 Deployment/Job spec 中添加需要的标签(applicationId 和 queue)来使用 YuniKorn 调度器运行 flink 应用程序,以及 [使用 YuniKorn 调度器运行 workloads](#run-workloads-with-yunikorn-scheduler) . - -## Native(原生)模式 - -请关注 [原生 Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/native_kubernetes.html) 以获取原生部署模式的细节和示例。 -只有 Flink 1.11 或更高版本才支持在 native 模式下使用 YuniKorn 调度程序运行 Flink 应用程序,我们可以利用两个 Flink 配置 `kubernetes.jobmanager.labels` 和 `kubernetes.taskmanager.labels` 来设置所需的标签。 -例子: - -* 启动一个 Flink session -``` -./bin/kubernetes-session.sh \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dresourcemanager.taskmanager-timeout=3600000 \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox -``` - -* 启动一个 Flink application -``` -./bin/flink run-application -p 8 -t kubernetes-application \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dkubernetes.container.image= \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - local:///opt/flink/usrlib/my-flink-job.jar -``` \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_mpi.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_mpi.md deleted file mode 100644 index 374c5ca1e68..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_mpi.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: run_mpi -title: 运行MPI作业 -description: 在Yunikorn中运行MPI作业 -keywords: - - mpi ---- - - - -本指南介绍将介绍如何设置[MPI Operator](https://github.com/kubeflow/mpi-operator),以及如何使用YuniKorn调度程序运行MPIJob。 - -## 安装MPI操作器 -您可以使用以下命令安装MPI操作器。如果您在安装时遇到问题,请参阅[此文档](https://github.com/kubeflow/mpi-operator)了解详细信息。 -``` -kubectl create -f https://raw.githubusercontent.com/kubeflow/mpi-operator/master/deploy/v2beta1/mpi-operator.yaml -``` - -## 运行MPI作业 -此示例显示如何运行MPI应用程序。 - -此程序将印出一些关于workers的基础信息,然后计算圆周率的近似值。 - -这是一个计算圆周率的[YAML示例](https://github.com/apache/yunikorn-k8shim/blob/master/deployments/examples/mpioperator/Pi/pi.yaml): - -```yaml -apiVersion: kubeflow.org/v2beta1 -kind: MPIJob -metadata: - name: pi -spec: - slotsPerWorker: 1 - runPolicy: - cleanPodPolicy: Running - ttlSecondsAfterFinished: 60 - sshAuthMountPath: /home/mpiuser/.ssh - mpiReplicaSpecs: - Launcher: - replicas: 1 - template: - labels: - applicationId: "mpi_job_pi" - queue: root.mpi - spec: - schedulerName: yunikorn - containers: - - image: mpioperator/mpi-pi - name: mpi-launcher - securityContext: - runAsUser: 1000 - command: - - mpirun - args: - - -n - - "2" - - /home/mpiuser/pi - resources: - limits: - cpu: 1 - memory: 1Gi - Worker: - replicas: 2 - template: - labels: - applicationId: "mpi_job_pi" - queue: root.mpi - spec: - schedulerName: yunikorn - containers: - - image: mpioperator/mpi-pi - name: mpi-worker - securityContext: - runAsUser: 1000 - command: - - /usr/sbin/sshd - args: - - -De - - -f - - /home/mpiuser/.sshd_config - resources: - limits: - cpu: 1 - memory: 1Gi -``` -创建一个MPIJob。 -``` -kubectl create -f deployments/examples/mpioperator/Pi/pi.yaml -``` - -我们在圆周率示例中添加了Yunikorn标签,以演示如何使用yunikorn调度程序。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_spark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_spark.md deleted file mode 100644 index 45791a18427..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/run_spark.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: run_spark -title: 运行Spark作业 -description: 如何使用YuniKorn运行Spark作业 -keywords: - - spark ---- - - - -:::note 注意 -本文档假设您已安装YuniKorn及其准入控制器。请参阅 [开始](../../get_started/get_started.md) 查看如何操作。 -::: - -## 为Spark准备docker镜像 - -要在Kubernetes上运行Spark,您需要Spark的docker镜像。您可以 -1)使用Spark团队提供的docker镜像 -2)从头开始构建一个镜像。如果你想建立自己的Spark的docker镜像,您可以找到 [完整说明](https://spark.apache.org/docs/latest/building-spark.html) -在 Spark 文档中。简化步骤: -* 下载一个支持Kubernetes的Spark版本,URL: https://github.com/apache/spark -* 构建支持Kubernetes的Spark版本: -```shell script -./buid/mvn -Pkubernetes -DskipTests clean package -``` -建议使用[dockerhub](https://hub.docker.com/r/apache/spark/tags)中不同spark版本的官方镜像 - -## 为Spark作业创建一个命名空间 - -创建一个命名空间: - -```shell script -cat < - -本章节概述了如何设置 [training-operator](https://github.com/kubeflow/training-operator) 以及如何使用 YuniKorn 调度器运行 Tensorflow 作业。 -training-operator 是由 Kubeflow 维护的一体化集成的训练 operator。它不仅支持 TensorFlow,还支持 PyTorch、XGboots 等。 - -## 安装 training-operator -您可以使用以下命令在 kubeflow 命名空间中默认安装 training operator。如果安装有问题, -请参阅 [此文档](https://github.com/kubeflow/training-operator#installation) 来查找相关的详细信息。 -``` -kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone?ref=v1.3.0" -``` - -## 准备 docker 镜像 -在开始于 Kubernetes 上运行 TensorFlow 作业之前,您需要构建 docker 镜像。 -1. 从 [deployment/examples/tfjob](https://github.com/apache/yunikorn-k8shim/tree/master/deployments/examples/tfjob) 上下载文件 -2. 使用以下命令构建这个 docker 镜像 - -``` -docker build -f Dockerfile -t kubeflow/tf-dist-mnist-test:1.0 . -``` - -## 运行一个 TensorFlow 作业 -以下是一个使用 MNIST [样例](https://github.com/apache/yunikorn-k8shim/blob/master/deployments/examples/tfjob/tf-job-mnist.yaml) 的 TFJob yaml. - -```yaml -apiVersion: kubeflow.org/v1 -kind: TFJob -metadata: - name: dist-mnist-for-e2e-test - namespace: kubeflow -spec: - tfReplicaSpecs: - PS: - replicas: 2 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 - Worker: - replicas: 4 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 -``` -创建 TFJob -``` -kubectl create -f deployments/examples/tfjob/tf-job-mnist.yaml -``` - -您可以从 YuniKorn UI 中查看作业信息。 如果您不知道如何访问 YuniKorn UI, -请阅读此 [文档](../../get_started/get_started.md#访问-web-ui)。 - -![tf-job-on-ui](../../assets/tf-job-on-ui.png) - -## 使用GPU Time-slicing -### 前提 -要使用 Time-slicing GPU,您需要先设定丛集以让GPU和Time-slicing GPU能被使用。 -- 节点上必须连接GPU -- Kubernetes版本为1.24 -- 丛集中需要安装 GPU drivers -- 透过 [GPU Operator](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/getting-started.html) 自动化的建置与管理节点中的 NVIDIA 软体组件 -- 在Kubernetes中设定 [Time-Slicing GPUs in Kubernetes](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/gpu-sharing.html) - - -在安装完 GPU Operator 及 Time-slicing GPU 以后,确认pods的状态以确保所有的containers正在运行或完成: -```shell script -kubectl get pod -n gpu-operator -``` -```shell script -NAME READY STATUS RESTARTS AGE -gpu-feature-discovery-fd5x4 2/2 Running 0 5d2h -gpu-operator-569d9c8cb-kbn7s 1/1 Running 14 (39h ago) 5d2h -gpu-operator-node-feature-discovery-master-84c7c7c6cf-f4sxz 1/1 Running 0 5d2h -gpu-operator-node-feature-discovery-worker-p5plv 1/1 Running 8 (39h ago) 5d2h -nvidia-container-toolkit-daemonset-zq766 1/1 Running 0 5d2h -nvidia-cuda-validator-5tldf 0/1 Completed 0 5d2h -nvidia-dcgm-exporter-95vm8 1/1 Running 0 5d2h -nvidia-device-plugin-daemonset-7nzvf 2/2 Running 0 5d2h -nvidia-device-plugin-validator-gj7nn 0/1 Completed 0 5d2h -nvidia-operator-validator-nz84d 1/1 Running 0 5d2h -``` -确认时间片设定是否被成功的使用: -```shell script -kubectl describe node -``` - -```shell script -Capacity: - nvidia.com/gpu: 16 -... -Allocatable: - nvidia.com/gpu: 16 -... -``` -### 使用GPU测试TensorFlow job -在这个段落中会在 Time-slicing GPU 的支援下,测试及验证TFJob的运行 - -1. 新建一个workload的测试档案tf-gpu.yaml: - ```shell script - vim tf-gpu.yaml - ``` - ```yaml - apiVersion: "kubeflow.org/v1" - kind: "TFJob" - metadata: - name: "tf-smoke-gpu" - namespace: kubeflow - spec: - tfReplicaSpecs: - PS: - replicas: 1 - template: - metadata: - creationTimestamp: - labels: - applicationId: "tf_job_20200521_001" - spec: - schedulerName: yunikorn - containers: - - args: - - python - - tf_cnn_benchmarks.py - - --batch_size=32 - - --model=resnet50 - - --variable_update=parameter_server - - --flush_stdout=true - - --num_gpus=1 - - --local_parameter_device=cpu - - --device=cpu - - --data_format=NHWC - image: docker.io/kubeflow/tf-benchmarks-cpu:v20171202-bdab599-dirty-284af3 - name: tensorflow - ports: - - containerPort: 2222 - name: tfjob-port - workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks - restartPolicy: OnFailure - Worker: - replicas: 1 - template: - metadata: - creationTimestamp: null - labels: - applicationId: "tf_job_20200521_001" - spec: - schedulerName: yunikorn - containers: - - args: - - python - - tf_cnn_benchmarks.py - - --batch_size=32 - - --model=resnet50 - - --variable_update=parameter_server - - --flush_stdout=true - - --num_gpus=1 - - --local_parameter_device=cpu - - --device=gpu - - --data_format=NHWC - image: docker.io/kubeflow/tf-benchmarks-gpu:v20171202-bdab599-dirty-284af3 - name: tensorflow - ports: - - containerPort: 2222 - name: tfjob-port - resources: - limits: - nvidia.com/gpu: 2 - workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks - restartPolicy: OnFailure - ``` -2. 创建TFJob - ```shell script - kubectl apply -f tf-gpu.yaml - ``` -3. 在Yunikorn中验证TFJob是否运行 - ![tf-job-gpu-on-ui](../../assets/tf-job-gpu-on-ui.png) - 察看pod的日志: - ```shell script - kubectl logs logs po/tf-smoke-gpu-worker-0 -n kubeflow - ``` - ``` - ....... - ..Found device 0 with properties: - ..name: NVIDIA GeForce RTX 3080 major: 8 minor: 6 memoryClockRate(GHz): 1.71 - - ....... - ..Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: NVIDIA GeForce RTX 3080, pci bus id: 0000:01:00.0, compute capability: 8.6) - ....... - ``` - ![tf-job-gpu-on-logs](../../assets/tf-job-gpu-on-logs.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/workload_overview.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/workload_overview.md deleted file mode 100644 index c7b46a4c378..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.2.0/user_guide/workloads/workload_overview.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: workload_overview -title: 概述 ---- - - - -YuniKorn调度器支持任何的Kubernetes工作负载。所需要的只是确保将Pod规范的 -`schedulerName`字段设置为`yunikorn`并将`applicationId`标签设置为每个应用程序的唯一值: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - labels: - app: sleep - applicationId: "application-sleep-0001" - name: sleep-app-1 -spec: - schedulerName: yunikorn - containers: - - name: sleep-30s - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "100M" -``` - -此外,如果存在YuniKorn准入控制器,则可以省略“schedulerName”字段,因为它将在新创建的pod上自动设置。 - -## 进阶例子 - -可以在此处找到更进阶的例子: - -* [运行Spark作业](run_spark) -* [运行Flink作业](run_flink) -* [运行TensorFlow作业](run_tf) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/cluster.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/cluster.md deleted file mode 100644 index 1f354d3b605..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/cluster.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -id: cluster -title: 集群 ---- - - - -## 集群 - -将回传Yunikorn所管理的集群的信息。信息包括应用程序的数量(包含总数、失败、挂起、正在运行、已完成)和容器的数量,以及资源管理器的构建信息。 - -**位置(URL)** : `/ws/v1/clusters` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**回传代码**:`200 OK` - -**示例** - -在本示例中,响应的内容来自一个群集,拥有一个资源管理器。 - -```json -[ - { - "startTime": 1649167576110754000, - "rmBuildInformation": [ - { - "buildDate": "2022-02-21T19:09:16+0800", - "buildVersion": "latest", - "isPluginVersion": "false", - "rmId": "rm-123" - } - ], - "partition": "default", - "clusterName": "kubernetes" - } -] -``` - -### 出错时的响应 - -**回传代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/scheduler.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/scheduler.md deleted file mode 100644 index 19b93279580..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/scheduler.md +++ /dev/null @@ -1,1484 +0,0 @@ ---- -id: scheduler -title: 调度器 ---- - - - -# 概要 - -Yunikorn调度器能透过REST API来返回多个对象的信息 -其中许多API将回传资源集合。在内部中,所有资源被「有符号的64位整数类型」所表示。当解析REST API的响应时,类型为`memory`的资源以bytes作为单位,而`vcore`则以一千表示一个CPU核心。而这两类之外的其他资源种类则没有具体指定。 - -在与app/node相关调用的响应中,包含一个`allocations`字段,而该字段中也包含多个字段。如`placeholderUsed`指的是分配是否是取代占位符(placeholder)。如果为true,`requestTime`将代表的是占位符的创建时间,如果为false,则就是代表这个分配(allocation)被询问时的时间。`allocationTime`则为分配被创建的时间,`allocationDelay`,则为`allocationTime`和`requestTime `相差的时间。 - -## 分区(Partitions) - -显示有关分区的一般信息和统计数据。 - -**位置(URL)**:`/ws/v1/partitions` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -```json -[ - { - "clusterId": "mycluster", - "name": "default", - "state": "Active", - "lastStateTransitionTime": 1649167576110754000, - "capacity": { - "capacity": { - "ephemeral-storage": 188176871424, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 1000000000, - "pods": 330, - "vcore": 1000 - }, - "usedCapacity": { - "memory": 800000000, - "vcore": 500 - }, - "utilization": { - "memory": 80, - "vcore": 50 - } - }, - "nodeSortingPolicy": { - "type": "fair", - "resourceWeights": { - "memory": 1.5, - "vcore": 1.3 - } - }, - "applications": { - "New": 5, - "Pending": 5, - "total": 10 - }, - "totalContainers": "0", - "totalNodes": "2" - }, - { - "clusterId": "mycluster", - "name": "gpu", - "state": "Active", - "lastStateTransitionTime": 1649167576111236000, - "capacity": { - "capacity": { - "memory": 2000000000, - "vcore": 2000 - }, - "usedCapacity": { - "memory": 500000000, - "vcore": 300 - }, - "utilization": { - "memory": 25, - "vcore": 15 - } - }, - "nodeSortingPolicy": { - "type": "binpacking", - "resourceWeights": { - "memory": 0, - "vcore": 4.11 - } - }, - "applications": { - "New": 5, - "Running": 10, - "Pending": 5, - "total": 20 - }, - "totalContainers": "20", - "totalNodes": "5" - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 队列(Queues) - -### 分区队列 - -获取给定分区中的队列,及队列相关的信息,其中包含名称、状态、容量和属性。 -队列层次结构(hierarchy)被保留在响应的json档中。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/queues` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -在预设的队列层次结构中(仅`root.default`),将会向客户端发送与以下相似的响应。 - -```json -[ - { - "queuename": "root", - "status": "Active", - "maxResource": { - "ephemeral-storage": 188176871424, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 8000000000, - "pods": 330, - "vcore": 8000 - }, - "guaranteedResource": { - "memory": 54000000, - "vcore": 80 - }, - "allocatedResource": { - "memory": 54000000, - "vcore": 80 - }, - "isLeaf": "false", - "isManaged": "false", - "properties": { - "application.sort.policy": "stateaware" - }, - "parent": "", - "template": { - "maxResource": { - "memory": 8000000000, - "vcore": 8000 - }, - "guaranteedResource": { - "memory": 54000000, - "vcore": 80 - }, - "properties": { - "application.sort.policy": "stateaware" - } - }, - "partition": "default", - "children": [ - { - "queuename": "root.default", - "status": "Active", - "maxResource": { - "memory": 8000000000, - "vcore": 8000 - }, - "guaranteedResource": { - "memory": 54000000, - "vcore": 80 - }, - "allocatedResource": { - "memory": 54000000, - "vcore": 80 - }, - "isLeaf": "true", - "isManaged": "false", - "properties": { - "application.sort.policy": "stateaware" - }, - "parent": "root", - "template": null, - "children": [], - "absUsedCapacity": { - "memory": 1, - "vcore": 0 - }, - "maxRunningApps": 12, - "runningApps": 4, - "allocatingAcceptedApps": [ - "app-1", - "app-2" - ] - } - ], - "absUsedCapacity": { - "memory": 1, - "vcore": 0 - } - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 多个应用程序 - -### 队列中多个应用程序 - -获取给定分区/队列组合的所有应用程序,并显示有关应用程序的信息,如使用的资源、队列名称、提交时间和分配。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/queue/{queueName}/applications` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -在下面的示例中,有三个分配属于两个应用程序,其中一个具有挂起(Pending)的请求。 - -```json -[ - { - "applicationID": "application-0001", - "usedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "maxUsedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "partition": "default", - "queueName": "root.default", - "submissionTime": 1648754032076020293, - "requests": [ - { - "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task2" - }, - "requestTime": 16487540320812345678, - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "pendingCount": 1, - "priority": "0", - "requiredNodeId": "", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderTimeout": 0, - "taskGroupName": "", - "allocationLog": [ - { - "message": "node(s) didn't match Pod's node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate", - "lastOccurrence": 16487540320812346001, - "count": 81 - }, - { - "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346002, - "count": 504 - }, - { - "message": "node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346003, - "count": 1170 - } - ] - } - ], - "allocations": [ - { - "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": true - } - ], - "applicationState": "Running", - "user": "system:serviceaccount:kube-system:deployment-controller", - "groups": [ - "system:serviceaccounts", - "system:serviceaccounts:kube-system", - "system:authenticated" - ], - "rejectedMessage": "", - "stateLog": [ - { - "time": 1648741409145224000, - "applicationState": "Accepted" - }, - { - "time": 1648741409145509400, - "applicationState": "Starting" - }, - { - "time": 1648741409147432100, - "applicationState": "Running" - } - ], - "placeholderData": [ - { - "taskGroupName": "task-group-example", - "count": 2, - "minResource": { - "memory": 1000000000, - "vcore": 100 - }, - "replaced": 1, - "timedout": 1 - } - ] - }, - { - "applicationID": "application-0002", - "usedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "maxUsedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "partition": "default", - "queueName": "root.default", - "submissionTime": 1648754032076020293, - "requests": [], - "allocations": [ - { - "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0002", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "08033f9a-4699-403c-9204-6333856b41bd", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0002", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - }, - { - "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0002", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task1" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0002", - "applicationId": "application-0002", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - } - ], - "applicationState": "Running", - "user": "system:serviceaccount:kube-system:deployment-controller", - "groups": [ - "system:serviceaccounts", - "system:serviceaccounts:kube-system", - "system:authenticated" - ], - "rejectedMessage": "", - "stateLog": [ - { - "time": 1648741409145224000, - "applicationState": "Accepted" - }, - { - "time": 1648741409145509400, - "applicationState": "Starting" - }, - { - "time": 1648741409147432100, - "applicationState": "Running" - } - ], - "placeholderData": [] - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 单一应用程序 - -### 队列中单一应用程序 - -从给定分区、队列和应用程序ID来获取应用程序,并显示有关应用程序的信息,如使用的资源、队列名称、提交时间和分配。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/queue/{queueName}/application/{appId}` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -```json -{ - "applicationID": "application-0001", - "usedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "maxUsedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "partition": "default", - "queueName": "root.default", - "submissionTime": 1648754032076020293, - "requests": [ - { - "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task2" - }, - "requestTime": 16487540320812345678, - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "pendingCount": 1, - "priority": "0", - "requiredNodeId": "", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderTimeout": 0, - "taskGroupName": "", - "allocationLog": [ - { - "message": "node(s) didn't match Pod's node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate", - "lastOccurrence": 16487540320812346001, - "count": 81 - }, - { - "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346002, - "count": 504 - }, - { - "message": "node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346003, - "count": 1170 - } - ] - } - ], - "allocations": [ - { - "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": true - } - ], - "applicationState": "Running", - "user": "system:serviceaccount:kube-system:deployment-controller", - "groups": [ - "system:serviceaccounts", - "system:serviceaccounts:kube-system", - "system:authenticated" - ], - "rejectedMessage": "", - "stateLog": [ - { - "time": 1648741409145224000, - "applicationState": "Accepted" - }, - { - "time": 1648741409145509400, - "applicationState": "Starting" - }, - { - "time": 1648741409147432100, - "applicationState": "Running" - } - ], - "placeholderData": [ - { - "taskGroupName": "task-group-example", - "count": 2, - "minResource": { - "memory": 1000000000, - "vcore": 100 - }, - "replaced": 1, - "timedout": 1 - } - ] -} -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 多个节点 - -### 分区中多个节点 - -获取给定分区的所有节点,并显示由YuniKorn管理的节点的信息。 -节点详细信息包括主机和机架名称、容量、资源、利用率和分配。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/nodes` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -这个示例的响应,来自一个群集,其中包含2个节点和3个分配。 - -```json -[ - { - "nodeID": "node-0001", - "hostName": "", - "rackName": "", - "capacity": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 14577000000, - "pods": 110, - "vcore": 10000 - }, - "allocated": { - "memory": 6000000000, - "vcore": 6000 - }, - "occupied": { - "memory": 154000000, - "vcore" :750 - }, - "available": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 6423000000, - "pods": 110, - "vcore": 1250 - }, - "utilized": { - "memory": 3, - "vcore": 13 - }, - "allocations": [ - { - "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "08033f9a-4699-403c-9204-6333856b41bd", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - }, - { - "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0002", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0002", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - } - ], - "schedulable": true - }, - { - "nodeID": "node-0002", - "hostName": "", - "rackName": "", - "capacity": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 14577000000, - "pods": 110, - "vcore": 10000 - }, - "allocated": { - "memory": 2000000000, - "vcore": 2000 - }, - "occupied": { - "memory": 154000000, - "vcore" :750 - }, - "available": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 6423000000, - "pods": 110, - "vcore": 1250 - }, - "utilized": { - "memory": 8, - "vcore": 38 - }, - "allocations": [ - { - "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task1" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0002", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - } - ], - "schedulable": true - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 单一节点 - -### 分区中单一节点 - -从给定分区和节点ID来获取节点,并显示有关节点的信息,节点详细信息包括主机和机架名称、容量、资源、利用率和分配。 - -**位置(URL)** : `/ws/v1/partition/{partitionName}/node/{nodeId}` - -**方法(Method)** : `GET` - -**需求权限** : NO - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -{ - "nodeID":"node-0001", - "hostName":"", - "rackName":"", - "capacity":{ - "ephemeral-storage":75850798569, - "hugepages-1Gi":0, - "hugepages-2Mi":0, - "memory":14577000000, - "pods":110, - "vcore":10000 - }, - "allocated":{ - "memory":6000000000, - "vcore":6000 - }, - "occupied":{ - "memory":154000000, - "vcore":750 - }, - "available":{ - "ephemeral-storage":75850798569, - "hugepages-1Gi":0, - "hugepages-2Mi":0, - "memory":6423000000, - "pods":110, - "vcore":1250 - }, - "utilized":{ - "memory":3, - "vcore":13 - }, - "allocations":[ - { - "allocationKey":"54e5d77b-f4c3-4607-8038-03c9499dd99d", - "allocationTags":{ - "kubernetes.io/label/app":"sleep", - "kubernetes.io/label/applicationId":"application-0001", - "kubernetes.io/label/queue":"root.default", - "kubernetes.io/meta/namespace":"default", - "kubernetes.io/meta/podName":"task0" - }, - "requestTime":1648754034098912461, - "allocationTime":1648754035973982920, - "allocationDelay":1875070459, - "uuid":"08033f9a-4699-403c-9204-6333856b41bd", - "resource":{ - "memory":2000000000, - "vcore":2000 - }, - "priority":"0", - "nodeId":"node-0001", - "applicationId":"application-0001", - "partition":"default", - "placeholder":false, - "placeholderUsed":false - }, - { - "allocationKey":"deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags":{ - "kubernetes.io/label/app":"sleep", - "kubernetes.io/label/applicationId":"application-0002", - "kubernetes.io/label/queue":"root.default", - "kubernetes.io/meta/namespace":"default", - "kubernetes.io/meta/podName":"task0" - }, - "requestTime":1648754034098912461, - "allocationTime":1648754035973982920, - "allocationDelay":1875070459, - "uuid":"9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource":{ - "memory":4000000000, - "vcore":4000 - }, - "priority":"0", - "nodeId":"node-0001", - "applicationId":"application-0002", - "partition":"default", - "placeholder":false, - "placeholderUsed":false - } - ], - "schedulable":true -} -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## Goroutines信息 - -获取当前运行的goroutines的堆栈跟踪(stack traces) - -**位置(URL)**:`/ws/v1/stack` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -```text -goroutine 356 [running -]: -github.com/apache/yunikorn-core/pkg/webservice.getStackInfo.func1(0x30a0060, -0xc003e900e0, -0x2) - /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 41 +0xab -github.com/apache/yunikorn-core/pkg/webservice.getStackInfo(0x30a0060, -0xc003e900e0, -0xc00029ba00) - /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 48 +0x71 -net/http.HandlerFunc.ServeHTTP(0x2df0e10, -0x30a0060, -0xc003e900e0, -0xc00029ba00) - /usr/local/go/src/net/http/server.go: 1995 +0x52 -github.com/apache/yunikorn-core/pkg/webservice.Logger.func1(0x30a0060, -0xc003e900e0, -0xc00029ba00) - /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/webservice.go: 65 +0xd4 -net/http.HandlerFunc.ServeHTTP(0xc00003a570, -0x30a0060, -0xc003e900e0, -0xc00029ba00) - /usr/local/go/src/net/http/server.go: 1995 +0x52 -github.com/gorilla/mux.(*Router).ServeHTTP(0xc00029cb40, -0x30a0060, -0xc003e900e0, -0xc0063fee00) - /yunikorn/go/pkg/mod/github.com/gorilla/mux@v1.7.3/mux.go: 212 +0x140 -net/http.serverHandler.ServeHTTP(0xc0000df520, -0x30a0060, -0xc003e900e0, -0xc0063fee00) - /usr/local/go/src/net/http/server.go: 2774 +0xcf -net/http.(*conn).serve(0xc0000eab40, -0x30a61a0, -0xc003b74000) - /usr/local/go/src/net/http/server.go: 1878 +0x812 -created by net/http.(*Server).Serve - /usr/local/go/src/net/http/server.go: 2884 +0x4c5 - -goroutine 1 [chan receive, - 26 minutes -]: -main.main() - /yunikorn/pkg/shim/main.go: 52 +0x67a - -goroutine 19 [syscall, - 26 minutes -]: -os/signal.signal_recv(0x1096f91) - /usr/local/go/src/runtime/sigqueue.go: 139 +0x9f -os/signal.loop() - /usr/local/go/src/os/signal/signal_unix.go: 23 +0x30 -created by os/signal.init.0 - /usr/local/go/src/os/signal/signal_unix.go: 29 +0x4f - -... -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 指标(Metrics) - -从Prometheus服务器检索指标的端点。 -指标中包含帮助消息和类型信息(type information)。 - -**位置(URL)** : `/ws/v1/metrics` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```text -# HELP go_gc_duration_seconds 作为垃圾收集周期的暂停期间的摘要。 -# TYPE go_gc_duration_seconds summary -go_gc_duration_seconds{quantile="0"} 2.567e-05 -go_gc_duration_seconds{quantile="0.25"} 3.5727e-05 -go_gc_duration_seconds{quantile="0.5"} 4.5144e-05 -go_gc_duration_seconds{quantile="0.75"} 6.0024e-05 -go_gc_duration_seconds{quantile="1"} 0.00022528 -go_gc_duration_seconds_sum 0.021561648 -go_gc_duration_seconds_count 436 -# HELP go_goroutines 当前存在的goroutines数量。 -# TYPE go_goroutines gauge -go_goroutines 82 -# HELP go_info 关于Golang环境的信息。 -# TYPE go_info gauge -go_info{version="go1.12.17"} 1 -# HELP go_memstats_alloc_bytes 已经被分配且正在使用的记忆体位元(bytes)数。 -# TYPE go_memstats_alloc_bytes gauge -go_memstats_alloc_bytes 9.6866248e+07 - -... - -# HELP yunikorn_scheduler_vcore_nodes_usage 节点的CPU使用量 -# TYPE yunikorn_scheduler_vcore_nodes_usage gauge -yunikorn_scheduler_vcore_nodes_usage{range="(10%, 20%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(20%,30%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(30%,40%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(40%,50%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(50%,60%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(60%,70%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(70%,80%]"} 1 -yunikorn_scheduler_vcore_nodes_usage{range="(80%,90%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(90%,100%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="[0,10%]"} 0 -``` - -## 配置验证 - -**位置(URL)** : `/ws/v1/validate-conf` - -**方法(Method)** : `POST` - -**需求权限**:无 - -### 成功时的响应 - -无论配置是否被允许,如果服务器能够处理请求,它都将生成一个200HTTP状态代码。 - -**返回代码** : `200 OK` - -#### 允许的配置 - -发送以下简单配置会被接受 - -```yaml -partitions: - - name: default - queues: - - name: root - queues: - - name: test -``` - -返回 - -```json -{ - "allowed": true, - "reason": "" -} -``` - -#### 不允许的配置 - -由于以下的的yaml档案中包含了“wrong_text”字段,因此是不允许的配置。 - -```yaml -partitions: - - name: default - queues: - - name: root - queues: - - name: test - - wrong_text -``` - -返回 - -```json -{ - "allowed": false, - "reason": "yaml: unmarshal errors:\n line 7: cannot unmarshal !!str `wrong_text` into configs.PartitionConfig" -} -``` - -## 配置 - -检索当前调度器配置的端点 - -**位置(URL)** : `/ws/v1/config` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```yaml -partitions: -- name: default - queues: - - name: root - parent: true - submitacl: '*' - placementrules: - - name: tag - create: true - value: namespace -checksum: D75996C07D5167F41B33E27CCFAEF1D5C55BE3C00EE6526A7ABDF8435DB4078E -``` - -## 应用程序历史 - -检索历史数据的端点,依据时间来条列应用程序的总数。 - -**位置(URL)** : `/ws/v1/history/apps` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -[ - { - "timestamp": 1595939966153460000, - "totalApplications": "1" - }, - { - "timestamp": 1595940026152892000, - "totalApplications": "1" - }, - { - "timestamp": 1595940086153799000, - "totalApplications": "2" - }, - { - "timestamp": 1595940146154497000, - "totalApplications": "2" - }, - { - "timestamp": 1595940206155187000, - "totalApplications": "2" - } -] -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 容器历史 - -检索历史数据的端点,依据时间来条列容器的总数。 - -**位置(URL)** : `/ws/v1/history/containers` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -[ - { - "timestamp": 1595939966153460000, - "totalContainers": "1" - }, - { - "timestamp": 1595940026152892000, - "totalContainers": "1" - }, - { - "timestamp": 1595940086153799000, - "totalContainers": "3" - }, - { - "timestamp": 1595940146154497000, - "totalContainers": "3" - }, - { - "timestamp": 1595940206155187000, - "totalContainers": "3" - } -] -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - - -## 健康检查的端点 - -用来检索历史数据的端点,其中包含关键日志,以及节点、集群、应用程序中资源量为负的资源。 - -**位置(URL)** : `/ws/v1/scheduler/healthcheck` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -{ - "Healthy": true, - "HealthChecks": [ - { - "Name": "Scheduling errors", - "Succeeded": true, - "Description": "Check for scheduling error entries in metrics", - "DiagnosisMessage": "There were 0 scheduling errors logged in the metrics" - }, - { - "Name": "Failed nodes", - "Succeeded": true, - "Description": "Check for failed nodes entries in metrics", - "DiagnosisMessage": "There were 0 failed nodes logged in the metrics" - }, - { - "Name": "Negative resources", - "Succeeded": true, - "Description": "Check for negative resources in the partitions", - "DiagnosisMessage": "Partitions with negative resources: []" - }, - { - "Name": "Negative resources", - "Succeeded": true, - "Description": "Check for negative resources in the nodes", - "DiagnosisMessage": "Nodes with negative resources: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if a node's allocated resource <= total resource of the node", - "DiagnosisMessage": "Nodes with inconsistent data: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if total partition resource == sum of the node resources from the partition", - "DiagnosisMessage": "Partitions with inconsistent data: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if node total resource = allocated resource + occupied resource + available resource", - "DiagnosisMessage": "Nodes with inconsistent data: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if node capacity >= allocated resources on the node", - "DiagnosisMessage": "Nodes with inconsistent data: []" - }, - { - "Name": "Reservation check", - "Succeeded": true, - "Description": "Check the reservation nr compared to the number of nodes", - "DiagnosisMessage": "Reservation/node nr ratio: [0.000000]" - } - ] -} -``` - -## 检索所有状态 - -能在单一响应包含以下的信息: - -* 分区清单 -* 应用程序清单(`运行中` 和 `已完成`) -* 应用程序历史 -* 节点 -* 节点的使用率 -* 集群的基本信息 -* 集群的使用率 -* 容器的历史 -* 队列 -* RM 诊断 - -**位置(URL)** : `/ws/v1/fullstatedump` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -该REST请求的输出将会很巨大,且为前面演示过的输出的组合。 - -RM 诊断显示 K8Shim 缓存的内容。确切内容取决于版本并且尚未稳定。 -当前内容显示缓存的对象: -* 节点 -* pods -* 优先等级 -* 调度状态(pod状态) - -### 错误时的响应 - -**代码**:`500 Internal Server Error` - -## 启用或禁用定期写入状态信息 - -为允许状态周期性地写入的端点。 - -**状态**:自v1.2.0以来已弃用并被忽略,无替代品。 - -**位置(URL)** : `/ws/v1/periodicstatedump/{switch}/{periodSeconds}` - -**方法(Method)** : `PUT` - -**需求权限**:无 - -### 成功时的响应 - -无 - -### 错误时的响应 - -**代码**: `400 Bad Request` - -## 获取日志级别 -接收当前Yunikorn的日志级别。 - -**URL** : `/ws/v1/loglevel` - -**方法** : `GET` - -**需求权限** : 无 - -### 成功时的响应 - -**代码**: `200 OK` - -**示例** - -``` -info% -``` - -## 设置日志级别 -设置Yunikorn日志级别。 - -**URL** : `/ws/v1/loglevel/{level}` - -**方法** : `PUT` - -**需求权限** : NO - -### 成功时的响应 - -**代码**: `200 OK` - -### 错误时的响应 - -**代码**: `400 Bad Request` - -**示例** - -```json -{ - "status_code":400, - "message":"failed to change log level, old level active", - "description":"failed to change log level, old level active" -} -``` - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/system.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/system.md deleted file mode 100644 index 83337cf4bc3..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/api/system.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -id: system -title: 系統 ---- - - - -这些端点是用于提供資訊給[pprof](https://github.com/google/pprof)分析工具。 - -## pprof - -**位置(URL)** : `/debug/pprof/` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```text -/debug/pprof/ - -Types of profiles available: -Count Profile -273 allocs -0 block -0 cmdline -78 goroutine -273 heap -0 mutex -0 profile -29 threadcreate -0 trace -full goroutine stack dump -Profile Descriptions: - -allocs: A sampling of all past memory allocations -block: Stack traces that led to blocking on synchronization primitives -cmdline: The command line invocation of the current program -goroutine: Stack traces of all current goroutines -heap: A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample. -mutex: Stack traces of holders of contended mutexes -profile: CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile. -threadcreate: Stack traces that led to the creation of new OS threads -trace: A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace. -``` - -## 堆 (Heap) - -**位置(URL)** : `/debug/pprof/heap` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 线程创建 - -**位置(URL)** : `/debug/pprof/threadcreate` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## Goroutine - -**位置(URL)** : `/debug/pprof/goroutine` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 分配 (Allocations) - -**位置(URL)** : `/debug/pprof/allocs` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 阻塞分析 (Block) - -**位置(URL)** : `/debug/pprof/block` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 互斥锁分析 (Mutex) - -**位置(URL)** : `/debug/pprof/mutex` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 命令行参数 (Cmdline) - -**位置(URL)** : `/debug/pprof/cmdline` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 简介 - -**位置(URL)** : `/debug/pprof/profile` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## Symbol - -**位置(URL)** : `/debug/pprof/symbol` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 跟踪(Trace) - -**位置(URL)** : `/debug/pprof/trace` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/assets b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/assets deleted file mode 120000 index 778d0f8e471..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/assets +++ /dev/null @@ -1 +0,0 @@ -../../../../docs/assets \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/developer_guide/env_setup.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/developer_guide/env_setup.md deleted file mode 100644 index e0ca816165a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/developer_guide/env_setup.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: env_setup -title: 开发环境的设置 ---- - - - -有很多种方法可以在本地设置Kubernetes开发环境,其中最常见的三种方法是`Minikube`([docs](https://kubernetes.io/docs/setup/minikube/))、`docker-desktop`和`kind`([kind](https://kind.sigs.k8s.io/) -`Minikube`通过数个虚拟机提供一个本地Kubernetes集群(通过VirtualBox或类似的东西)。`docker-desktop`能在docker容器中设置Kubernetes集群。 `kind`为Windows、Linux和Mac提供轻量级的Kubernetes集群。 - -## 使用Docker Desktop设置本地的Kubernetes集群 - -在本教程中,我们将基于Docker Desktop进行所有的安装。 -我们也可以使用轻量级的[minikube](#使用minikube设置本地的kubernetes集群)设置,它可以提供同样的功能,且需要的资源较小。 - -### 安装 - -在你的笔记本电脑上下载并安装[Docker-Desktop](https://www.docker.com/products/docker-desktop)。其中,最新版本包含了Kubernetes,所以不需要额外安装。 -只需按照[这里](https://docs.docker.com/docker-for-mac/#kubernetes)的步骤,就可以在docker-desktop中启动和运行Kubernetes。 - -一旦Kubernetes在docker桌面中启动,你应该看到类似以下的画面: - -![Kubernetes in Docker Desktop](./../assets/docker-desktop.png) - -这意味着: -1. Kubernetes正在运行。 -2. 命令行工具`kubctl`安装在`/usr/local/bin`目录下。 -3. Kubernetes的被设置到`docker-desktop`中。 - -### 部署和访问仪表板 - -设置好本地Kubernetes后,你需要使用以下步骤部署仪表盘: -1. 按照[Kubernetes dashboard doc](https://github.com/kubernetes/dashboard)中的说明来部署仪表盘。 -2. 从终端启动Kubernetes代理,让我们能存取本地主机上的仪表板: - ```shell script - kubectl proxy & - ``` -3. 通过以下网址访问仪表板: [链接](http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login) - -### 访问本地Kubernetes集群 - -上一步部署的仪表板需要一个令牌或配置来登录。这里我们使用令牌来登录。该令牌是自动生成的,可以从系统中检索到。 - -1. 检索仪表板令牌的名称: - ```shell script - kubectl -n kube-system get secret | grep kubernetes-dashboard-token - ``` -2. 检索令牌的内容,注意令牌名称以随机的5个字符代码结尾,需要用步骤1的结果替换。例如: - ```shell script - kubectl -n kube-system describe secret kubernetes-dashboard-token-tf6n8 - ``` -3. 複製`Data`中标签为 `token`的值。 -4. 在用户介面仪表板中选择 **Token**:
- ![Token Access in dashboard](./../assets/dashboard_token_select.png) -5. 在输入框中粘贴`token`的值,然后登录:
- ![Token Access in dashboard](./../assets/dashboard_secret.png) - -## 使用Minikube设置本地的Kubernetes集群 - -Minikube 可以被添加到现有的 Docker Desktop 中。Minikube 既可以使用预装的虚拟机管理程序(hypervisor),也可以自己选择。预设是由[HyperKit](https://github.com/moby/hyperkit)所提供的虚拟化,它已被嵌入到 Docker Desktop 中。 - -如果你不想使用 HyperKit 的虚拟机管理程序,请确保你遵循通用的minikube安装说明。如果需要的话,不要忘记为所选择的虚拟机管理程序安装正确的驱动程序。 -基本说明在[minikube install](https://kubernetes.io/docs/tasks/tools/install-minikube/)中提供。 - -如果要检查 Docker Desktop 是否安装了 HyperKit。在终端上运行: `hyperkit`来确认。除了 `hyperkit: command not found` 以外的任何响应都证实了 HyperKit 已经安装并且在路径上。如果没有找到,你可以选择一个不同的虚拟机管理程序或修复Docker Desktop。 - -### 安装 Minikube -1. 你可以使用 brew 或是以下的步骤来安装 minikube: - ```shell script - curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 - chmod +x minikube - sudo mv minikube /usr/local/bin - ``` -2. 你可以使用 brew 或是以下的步骤来安装 HyperKit 的驱动程序(必要): - ```shell script - curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-hyperkit - sudo install -o root -g wheel -m 4755 docker-machine-driver-hyperkit /usr/local/bin/ - ``` -3. 更新 minikube 配置,使其默认虚拟机管理程序为HyperKit:`minikube config set vm-driver hyperkit`。 -4. 修改 docker desktop 以使用 Kubernetes 的 minikube:
- ![Kubernetes in Docker Desktop: minikube setting](./../assets/docker-dektop-minikube.png) - -### 部署和访问集群 -安装完成后,你可以开始启动一个新的集群。 -1. 启动 minikube 集群: `minikube start --kubernetes-version v1.24.7` -2. 启动 minikube 仪表板: `minikube dashboard &` - -### 开发环境对构建的影响 -在创建映像之前,确保你的 minikube 运行在正确的环境中。 -如果没有设定 minikube 环境,就会在部署调度器的时候找不到docker映像。 -1. 确保 minikube 已启动。 -2. 在你要运行构建的终端中,执行: `eval $(minikube docker-env)` -3. 在 yunikorn-k8shim 的根目录创建映像: `make image` -4. 按照正常指令部署调度器。 - -## 使用 Kind 的设置本地的 Kubernetes 集群 - -Kind(Kubernetes in Docker)是一个轻量级的工具,主要用来运行轻量级Kubernetes环境。 用kind测试不同的Kubernetes版本是非常容易的,只需选择你想要的映像。 - -### 安装 - -如果你已经安装过go,可以直接运行`go install sigs.k8s.io/kind@latest`。 - -可在[Kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)的文件上找到其他方法。 - -要将 Kind 与 Kubernetes 1.25 一起使用,您需要使用 v0.15 或更高版本的 Kind。有些kind版本仅支持特定版本的Kubernetes,您可以从Kind发布的说明中获取该信息。 - -### 使用 Kind - -若要要测试新版本的Kubernetes,你可以从kind的repo中拉出一个相应的映像。 - -创建版本为 v1.24.7 的 Kubernetes 集群: `kind create cluster --name test --image kindest/node:v1.24.7` - -删除 kind 集群: `kind delete cluster --name test` - -### 载入你的映像 - -为了使用本地镜像,你必须将你的映像加载到kind的注册表(registry)中。 如果你运行`make image`,你可以使用下面的命令来加载你的kind映像。 以下假设为AMD64架构。 - -下面是调度器、网页UI和存取控制器的例子: - -调度器: -`kind load docker-image apache/yunikorn:scheduler-amd64-latest` - -网页UI: -`kind load docker-image apache/yunikorn:web-amd64-latest` - -存取控制器: -`kind load docker-image apache/yunikorn:admission-amd64-latest` - -## 在本地调试代码 - -注意,这个指令要求你在 GoLand IDE 进行开发。 - -在GoLand中,进入yunikorn-k8shim项目。然后点击 "Run" -> "Debug..." -> "Edit Configuration..." 获取弹出的配置窗口。 -注意,如果第一次没有 "Go Build "选项,你需要点击 "+"来创建一个新的配置文件。 - -![Debug Configuration](./../assets/goland_debug.jpg) - -强调的字段是你需要添加的配置。包括以下: - -- Run Kind: package -- Package path: 指向 `pkg/shim` 的路径 -- Working directory: 指向`conf`目录的路径,这是程序加载配置文件的地方。 -- Program arguments: 指定运行程序的参数,如 `-kubeConfig=/path/to/.kube/config -interval=1s -clusterId=mycluster -clusterVersion=0.1 -name=yunikorn -policyGroup=queues -logEncoding=console -logLevel=-1`. -注意,你需要把`/path/to/.kube/config`替换为kubeconfig文件的本地路径。如果你想改变或添加更多的选项,你可以运行`_output/bin/k8s-yunikorn-scheduler -h`来了解。 - -修改完成后,点击 "Apply",然后点击 "Debug"。你将需要设置适当的断点,以便调试程序。 - -## 存取远端的 Kubernetes 集群 - -这个设置的前提是你已经安装了一个远程Kubernetes集群。 -关于如何访问多个集群并将其整合,请参考Kubernetes的[访问多个集群](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)文档。 - -或者按照这些简化的步骤: -1. 从远程集群获取Kubernetes的`config`文件,将其复制到本地机器上,并给它一个唯一的名字,即`config-remote`。 -2. 更新 `KUBECONFIG` 环境变量(如果已设置)。 - ```shell script - export KUBECONFIG_SAVED=$KUBECONFIG - ``` -3. 将新文件添加到环境变量中。 - ```shell script - export KUBECONFIG=$KUBECONFIG:config-remote - ``` -4. 运行`kubectl config view`命令,检查是否可以访问这两个配置。 -5. 透过以下命令切换配置 `kubectl config use-context my-remote-cluster` -6. 确认是否切换到了远程集群的配置: - ```text - kubectl config get-contexts - CURRENT NAME CLUSTER AUTHINFO NAMESPACE - docker-for-desktop docker-for-desktop-cluster docker-for-desktop - * my-remote-cluster kubernetes kubernetes-admin - ``` - -更多的文件可以在[这里](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)找到。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/developer_guide/translation.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/developer_guide/translation.md deleted file mode 100644 index 2e74494ed86..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/developer_guide/translation.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: translation -title: 翻译 ---- - - - -Yunikorn网站采用Docusaurus管理文档。 -[Docusaurus国际化系统(i18n)](https://docusaurus.io/docs/i18n/tutorial)允许开发人员翻译文档。 -为网站添加新的语言翻译时,开发者应进行如下操作。 - -## 修改docusaurus.config.js以支持新语言 -假设通过**新语言关键字**进行翻译。 -预期的结果会像这个图(右上方的<新语言关键字>為test)。 -![翻译结果](./../assets/translationDemo.png) - -当前的Yunikorn网站包括**en**和**zh-cn**文档。 -如果开发者想添加一个新的带有**新语言关键字**的翻译,如fr, jp。 -则开发者需要修改`docusaurus.config.js`中的`i18n`栏位。 -``` -i18n: { - defaultLocale: 'en', - locales: ['en', 'zh-cn', '<新语言关键字>'], - localeConfigs: { - en: { - label: 'English', - }, - "zh-cn": { - label: '中文', - }, - "<新语言关键字>": { - label: 'test', - } - }, - }, -``` -## 更新local-build.sh中的帮助信息 -将**新语言关键字**添加到`print_usage`函数的语言环境列表中。 -``` -Usage: $(basename "$0") run [locale] | build | clean | help - run build the website, and launch the server in a docker image. - a locale can be specified, currently supported: "en", "zh-cn", "<新语言关键字>" -``` - -## 将最新文件复制到i18n资料夹 -``` -mkdir -p i18n/<新语言关键字>/docusaurus-plugin-content-docs/current -cp -r docs/** i18n/<新语言关键字>/docusaurus-plugin-content-docs/current -mkdir -p i18n/<新语言关键字>/docusaurus-plugin-content-pages -cp -r src/pages/** i18n/<新语言关键字>/docusaurus-plugin-content-pages -mkdir -p i18n/<新语言关键字>/docusaurus-theme-classic -``` - -## 在sidebar.json和footer.json中添加翻译后的信息 -在docusaurus-theme-classic资料夹中创建sidebar.json和footer.json档案。 -例如,添加的footer.json内容如下。 -``` -{ - "link.item.label.Get Involved": { - "message": "参与" - }, - "link.title.Code Repositories": { - "message": "代码库" - }, - "link.item.label.People": { - "message": "人们" - }, - "link.title.Blog": { - "message": "博客" - }, - "link.title.Community": { - "message": "社区" - } -} -``` - - - -## 链接img、assest与styles.module.css -在`i18n/new language keyword/docusaurus-plugin-content-pages`中创建链接文件。 - -``` -# 清理重复文件 -rm -rf img -rm styles.module.css -# 链接 -ln -s ../../../static/img -ln -s ../../../src/pages/styles.module.css -``` - -在`i18n/new language keyword/docusaurus-plugin-content-docs/current`中创建链接文件。 -``` -# 清理重复文件 -rm -rf assests -# 链接 -ln -s ../../../../docs/assets -``` - -## 采用相对路径 -`src/pages/index.js`中有部分图片url采用绝对路径,采用绝对路径会导致png丢失。 -开发人员需要确保`/i18n/new language keyword/docusaurus-plugin-content-pages/index.js`中的图链接有效。 -例如,在`index.js`中有一个`resource-scheduling.png`图像,图像链接是`/img/resource-scheduling.png`。 -``` -/img/resource-scheduling.png -> ./img/resource-scheduling.png -``` -## 测试 -``` -./local-build.sh run <新语言关键字> -``` -![建设网站](./../assets/translationBuilding.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/get_started/core_features.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/get_started/core_features.md deleted file mode 100644 index d6d3c497992..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/get_started/core_features.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: core_features -title: 特征 -keywords: - - 特征 ---- - - - -YuniKorn的主要特点包括: - -## 应用感知调度 - -YuniKorn的关键特性之一就是支持应用感知。在默认的K8s调度程序中,它只能根据Pod进行调度,而不能基于用户、作业或者队列进行更细粒度的调度。 -与之不同的是,YuniKorn可以识别用户、作业或者队列,并在做出调度决策时,考虑更多与它们相关的因素,如资源、排序等。 -这使我们能够对资源配额、资源公平性和优先级进行细粒度控制,这是多租户计算系统最重要的需求。 - -## 层次资源队列 - -层次队列提供了一种有效的机制来管理集群资源。 -队列的层次结构可以在逻辑上映射到组织结构。这为不同租户提供了对资源的细粒度控制。 -YuniKorn UI 提供了一个集中的视图来监视资源队列的使用情况,它可以帮助您了解不同租户是如何使用资源的。 -此外,用户可以利用设置最小/最大队列容量来为每个租户设定其弹性资源配额。 - -## 作业排序和排队 - -YuniKorn将每个资源队列中的队列进行排队,排序策略决定哪个应用程序可以首先获得资源。 -这个策略可以是多种多样的,例如简单的 `FIFO`、`Fair`、`StateAware` 或基于 `Priority` 的策略。 -队列可以维持应用的顺序,调度器根据不同的策略为作业分配相应的资源。这种行为更容易被理解和控制。 - -此外,当配置队列最大容量时,作业和任务可以在资源队列中正确排队。 -如果剩余的容量不够,它们可以排队等待,直到释放一些资源。这就简化了客户端操作。 -而在默认调度程序中,资源由命名空间资源配额限制:如果命名空间没有足够的配额,Pod就不能被创建。这是由配额许可控制器强制执行的。 -客户端需要更复杂的逻辑来处理此类场景,例如按条件重试。 - -## 资源公平性 - -在多租户环境中,许多用户共享集群资源。 -为了避免租户争夺资源或者可能的资源不足,需要做到更细粒度的公平性需求,以此来实现跨用户以及跨团队/组织的公平性。 -考虑到权重或优先级,一些更重要的应用可以获得超过其配额的更多的需求资源。 -这往往与资源预算有关,更细粒度的公平模式可以进一步提高资源控制。 - -## 资源预留 - -YuniKorn会自动为未完成的请求进行资源预留。 -如果Pod无法分配,YuniKorn将尝试把它预留在一个满足条件的节点上,并在这个节点上暂时分配该 pod(在尝试其他节点之前)。 -这种机制可以避免这个 Pod 需要的资源被后来提交的更小的、更不挑剔的 Pod 所挤占。 -此功能在批处理工作负载场景中非常重要,因为当对集群提交大量异构 Pod 时,很有可能一些 Pod 会处于“饥饿”状态,即使它们提交得更早。 - -## 吞吐量 - -吞吐量是衡量调度器性能的关键标准。这对于一个大规模的分布式系统来说是至关重要的。 -如果吞吐量不好,应用程序可能会浪费时间等待调度,并进一步影响服务的 SLA(服务级别协议)。 -集群越大,对吞吐量的要求也越高。[基于Kube标记的运行评估](performance/evaluate_perf_function_with_kubemark.md) 章节显示了一些性能数据。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/get_started/get_started.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/get_started/get_started.md deleted file mode 100644 index fcf009f0f5e..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/get_started/get_started.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: user_guide -title: 开始 -slug: / ---- - - - -在阅读本指南之前,我们假设您有一个Kubernetes集群或本地 Kubernetes 开发环境,例如 MiniKube。 -还假定 `kubectl` 在您的环境路径内,并且配置正确。 -遵循此 [指南](developer_guide/env_setup.md) 来讲述如何使用 docker-desktop 设置本地Kubernetes集群。 - -## 安装 - -最简单的方法是使用我们的 Helm Chart 在现有的Kubernetes集群上部署YuniKorn。 -我们建议使用 Helm 3 或更高版本。 - -```shell script -helm repo add yunikorn https://apache.github.io/yunikorn-release -helm repo update -kubectl create namespace yunikorn -helm install yunikorn yunikorn/yunikorn --namespace yunikorn -``` - -默认情况下,Helm Chart 将在集群中安装调度器、web服务器和 admission-controller。 -`admission-controller` 一旦安装,它将把所有集群流量路由到YuniKorn。 -这意味着资源调度会委托给YuniKorn。在Helm安装过程中,可以通过将 `embedAdmissionController` 标志设置为 `false` 来禁用它。 -通过将Helm的 `enableSchedulerPlugin` 标志设置为 `true`,YuniKorn调度器也可以以Kubernetes的调度器插件的方式进行部署。 -这种方式将会部署一个包含与默认调度器一起编译的YuniKorn备用Docker镜像。 -这种新模式借助默认的Kubernetes调度器提供了更好的兼容性,并且适合与将所有调度委托给YuniKorn的 admission-controller 协同使用。 -因为这个模式还是很新的,所以默认没有开启。 - -如果您不确定应该使用哪种部署模式,请参阅我们 [并列比较](user_guide/deployment_modes) 章节的内容。 - -如果你不想使用 Helm Chart,您可以找到我们的细节教程 [点击这里](developer_guide/deployment.md) 。 - -## 卸载 - -运行如下的命令卸载 YuniKorn: - -```shell script -helm uninstall yunikorn --namespace yunikorn -``` - -## 访问 Web UI - -当部署调度程序时,Web UI 也会部署在容器中。 -我们可以通过以下方式在标准端口上打开 Web 界面的端口转发: - -```shell script -kubectl port-forward svc/yunikorn-service 9889:9889 -n yunikorn -``` - -`9889` 是 Web UI 的默认端口。 -完成此操作后,web UI将在以下地址可用: http://localhost:9889 。 - -![UI 截图](./../assets/yk-ui-screenshots.gif) - -YuniKorn UI 提供了集群资源容量、利用率和所有应用信息的集中视图。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/evaluate_perf_function_with_kubemark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/evaluate_perf_function_with_kubemark.md deleted file mode 100644 index 44f4c67ebda..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/evaluate_perf_function_with_kubemark.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: evaluate_perf_function_with_kubemark -title: 使用 Kubemark 评估 YuniKorn 的性能 -keywords: - - 性能 - - 吞吐量 ---- - - - -YuniKorn 社区关注调度程序的性能,并继续在发布时对其进行优化。 社区已经开发了一些工具来反复测试和调整性能。 - -## 环境设置 - -我们利用[Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster)评估调度器的性能。 Kubemark是一个模拟大规模集群的测试工具。 它创建空节点,运行空kubelet以假装原始kubelet行为。 这些空节点上的调度pod不会真正执行。它能够创建一个满足我们实验要求的大集群,揭示yunikorn调度器的性能。 请参阅有关如何设置环境的[详细步骤](performance/performance_tutorial.md)。 - -## 调度程序吞吐量 - -我们在模拟的大规模环境中设计了一些简单的基准测试场景,以评估调度器的性能。 我们的工具测量[吞吐量](https://en.wikipedia.org/wiki/Throughput)并使用这些关键指标来评估性能。 简而言之,调度程序吞吐量是处理pod从在集群上发现它们到将它们分配给节点的速率。 - -在本实验中,我们使用 [Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster) 设置了一个模拟的2000/4000节点集群。然后我们启动10个[部署](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/),每个部署分别设置5000个副本。 这模拟了大规模工作负载同时提交到K8s集群。 我们的工具会定期监控和检查pod状态,随着时间的推移,根据 `podSpec.StartTime` 计算启动的pod数量。 作为对比,我们将相同的实验应用到相同环境中的默认调度程序。 我们看到了YuniKorn相对于默认调度程序的性能优势,如下图所示: - -![Scheduler Throughput](./../assets/yunirkonVSdefault.png) -

图 1. Yunikorn 和默认调度器吞吐量

- -图表记录了集群上所有 Pod 运行所花费的时间: - -| 节点数 | yunikorn | k8s 默认调度器 | 差异 | -|------------------ |:--------------: |:---------------------: |:-----: | -| 2000(节点) | 204(pods/秒) | 49(pods/秒) | 416% | -| 4000(节点) | 115(pods/秒) | 48(pods/秒) | 240% | - -为了使结果标准化,我们已经运行了几轮测试。 如上所示,与默认调度程序相比,YuniKorn实现了`2 倍`~`4 倍`的性能提升。 - -:::note - -与其他性能测试一样,结果因底层硬件而异,例如服务器CPU/内存、网络带宽、I/O速度等。为了获得适用于您的环境的准确结果,我们鼓励您运行这些测试在靠近生产环境的集群上。 - -::: - -## 性能分析 - -我们从实验中得到的结果是有希望的。 我们通过观察更多的YuniKorn内部指标进一步深入分析性能,我们能够找到影响性能的几个关键区域。 - -### K8s 限制 - -我们发现整体性能实际上受到了K8s主服务的限制,例如api-server、controller-manager和etcd,在我们所有的实验中都没有达到YuniKorn的限制。 如果您查看内部调度指标,您可以看到: - -![Allocation latency](./../assets/allocation_4k.png) -

图 2. 4k 节点中的 Yunikorn 指标

- -图2是Prometheus的截图,它记录了YuniKorn中的[内部指标](performance/metrics.md) `containerAllocation`。 它们是调度程序分配的 pod 数量,但不一定绑定到节点。 完成调度50k pod大约需要122秒,即410 pod/秒。 实际吞吐量下降到115个 Pod/秒,额外的时间用于绑定不同节点上的Pod。 如果K8s方面能赶上来,我们会看到更好的结果。 实际上,当我们在大规模集群上调整性能时,我们要做的第一件事就是调整API-server、控制器管理器中的一些参数,以提高吞吐量。 在[性能教程文档](performance/performance_tutorial.md)中查看更多信息。 - -### 节点排序 - -当集群大小增加时,我们看到YuniKorn的性能明显下降。 这是因为在YuniKorn中,我们对集群节点进行了完整排序,以便为给定的pod找到 **“best-fit”** 节点。 这种策略使Pod分布更加优化,基于所使用的 [节点排序策略](./../user_guide/sorting_policies#node-sorting)。 但是,对节点进行排序很昂贵,在调度周期中这样做会产生很多开销。 为了克服这个问题,我们在 [YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807) 中改进了我们的节点排序机制,其背后的想法是使用 [B-Tree ](https://en.wikipedia.org/wiki/B-tree)来存储所有节点并在必要时应用增量更新。 这显着改善了延迟,根据我们的基准测试,这在500、1000、2000 和 5000个节点的集群上分别提高了 35 倍、42 倍、51 倍、74 倍。 - -### 每个节点的前提条件检查 - -在每个调度周期中,另一个耗时的部分是节点的“前提条件检查”。 在这个阶段,YuniKorn评估所有K8s标准断言(Predicates),例如节点选择器、pod亲和性/反亲和性等,以确定pod是否适合节点。 这些评估成本很高。 - -我们做了两个实验来比较启用和禁用断言评估的情况。 请参阅以下结果: - -![Allocation latency](./../assets/predicateComaparation.png) -

图 3. Yunikorn 中的断言效果比较

- -当断言评估被禁用时,吞吐量会提高很多。 我们进一步研究了整个调度周期的延迟分布和断言评估延迟。 并发现: - -![YK predicate latency](./../assets/predicate_4k.png) -

图 4. 断言延迟

- -![YK scheduling with predicate](./../assets/scheduling_with_predicate_4k_.png) -

图 5. 启用断言的调度时间

- -![YK scheduling with no predicate](./../assets/scheduling_no_predicate_4k.png) -

图 6. 不启用断言的调度时间

- -总体而言,YuniKorn 调度周期运行得非常快,每个周期的延迟下降在 **0.001s - 0.01s** 范围内。 并且大部分时间用于断言评估,10倍于调度周期中的其他部分。 - -| | 调度延迟分布(秒) | 断言-评估延迟分布(秒) | -|----------------------- |:---------------------: |:---------------------: | -| 启用断言 | 0.01 - 0.1 | 0.01-0.1 | -| 不启用断言 | 0.001 - 0.01 | 无 | - -## 为什么 YuniKorn 更快? - -默认调度器被创建为面向服务的调度器; 与YuniKorn相比,它在吞吐量方面的敏感性较低。 YuniKorn社区非常努力地保持出色的性能并不断改进。 YuniKorn可以比默认调度器运行得更快的原因是: - -* 短调度周期 - -YuniKorn 保持调度周期短而高效。 YuniKorn 使用所有异步通信协议来确保所有关键路径都是非阻塞调用。 大多数地方只是在进行内存计算,这可能非常高效。 默认调度器利用 [调度框架](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/),它为扩展调度器提供了很大的灵活性,但是,权衡是性能。 调度周期变成了一条很长的链,因为它需要访问所有这些插件。 - -* 异步事件处理 - -YuniKorn利用异步事件处理框架来处理内部状态。 这使得核心调度周期可以快速运行而不会被任何昂贵的调用阻塞。 例如,默认调度程序需要将状态更新、事件写入pod对象,这是在调度周期内完成的。 这涉及将数据持久化到etcd,这可能很慢。 YuniKorn将所有此类事件缓存在一个队列中,并以异步方式写回pod。 - -* 更快的节点排序 - -[YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807)之后,YuniKorn进行了高效的增量节点排序。 这是建立在所谓的基于“资源权重”的节点评分机制之上的,它也可以通过插件进行扩展。 所有这些一起减少了计算节点分数时的开销。 相比之下,默认调度器提供了一些计算节点分数的扩展点,例如`PreScore`、`Score`和`NormalizeScore`。 这些计算量很大,并且在每个调度周期中都会调用它们。 请参阅[代码行](https://github.com/kubernetes/kubernetes/blob/481459d12dc82ab88e413886e2130c2a5e4a8ec4/pkg/scheduler/framework/runtime/framework.go#L857)中的详细信息。 - -## 概括 - -在测试过程中,我们发现YuniKorn的性能非常好,尤其是与默认调度程序相比。 我们已经确定了YuniKorn中可以继续提高性能的主要因素,并解释了为什么YuniKorn的性能优于默认调度程序。 我们还意识到将Kubernetes扩展到数千个节点时的局限性,可以通过使用其他技术(例如联合)来缓解这些局限性。 因此,YuniKorn是一个高效、高吞吐量的调度程序,非常适合在Kubernetes上运行批处理/混合工作负载。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/metrics.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/metrics.md deleted file mode 100644 index 7d6fa73e5b8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/metrics.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: metrics -title: 调度程序指标 -keywords: - - 指标 ---- - - - -YuniKorn利用[Prometheus](https://prometheus.io/) 记录指标。 度量系统不断跟踪调度程序的关键执行路径,以揭示潜在的性能瓶颈。 目前,这些指标分为三类: - -- 调度器:调度器的通用指标,例如分配延迟、应用程序数量等。 -- 队列:每个队列都有自己的指标子系统,跟踪队列状态。 -- 事件:记录YuniKorn中事件的各种变化。 - -所有指标都在`yunikorn`命名空间中声明。 -### 调度程序指标 - -| 指标名称 | 指标类型 | 描述 | -| --------------------- | ------------ | ------------ | -| containerAllocation | Counter | 尝试分配容器的总次数。 尝试状态包括`allocated`, `rejected`, `error`, `released`。 该指标只会增加。 | -| applicationSubmission | Counter | 提交申请的总数。 尝试的状态包括 `accepted`和`rejected`。 该指标只会增加。 | -| applicationStatus | Gauge | 申请状态总数。 应用程序的状态包括`running`和`completed`。 | -| totalNodeActive | Gauge | 活动节点总数。 | -| totalNodeFailed | Gauge | 失败节点的总数。 | -| nodeResourceUsage | Gauge | 节点的总资源使用情况,按资源名称。 | -| schedulingLatency | Histogram | 主调度例程的延迟,以秒为单位。 | -| nodeSortingLatency | Histogram | 所有节点排序的延迟,以秒为单位。 | -| appSortingLatency | Histogram | 所有应用程序排序的延迟,以秒为单位。 | -| queueSortingLatency | Histogram | 所有队列排序的延迟,以秒为单位。 | -| tryNodeLatency | Histogram | 节点条件检查容器分配的延迟,例如放置约束,以秒为单位。 | - -### 队列指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------- | ------------- | ----------- | -| appMetrics | Counter | 应用程序指标,记录申请总数。 应用程序的状态包括`accepted`、`rejected`和`Completed`。 | -| usedResourceMetrics | Gauge | 排队使用的资源。 | -| pendingResourceMetrics | Gauge | 排队等待的资源。 | -| availableResourceMetrics | Gauge | 与队列等相关的已用资源指标。 | - -### 事件指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------ | ------------ | ----------- | -| totalEventsCreated | Gauge | 创建的事件总数。 | -| totalEventsChanneled | Gauge | 引导的事件总数。 | -| totalEventsNotChanneled | Gauge | 引导的事件总数。 | -| totalEventsProcessed | Gauge | 处理的事件总数。 | -| totalEventsStored | Gauge | 存储的事件总数。 | -| totalEventsNotStored | Gauge | 未存储的事件总数。 | -| totalEventsCollected | Gauge | 收集的事件总数。 | - -## 访问指标 - -YuniKorn指标通过Prometheus客户端库收集,并通过调度程序RESTful服务公开。 -启动后,可以通过端点http://localhost:9080/ws/v1/metrics访问它们。 - -## Prometheus 的聚合指标 - -设置 Prometheus 服务器以定期获取 YuniKorn 指标很简单。 按着这些次序: - -- 设置Prometheus(从[Prometheus 文档](https://prometheus.io/docs/prometheus/latest/installation/)了解更多信息) - -- 配置Prometheus规则:示例配置 - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] -``` - -- 启动 Prometheus - -```shell script -docker pull prom/prometheus:latest -docker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus -``` - -如果您在Mac OS上的本地docker容器中运行Prometheus,请使用`docker.for.mac.host.internal`而不是`localhost`。 启动后,打开Prometheus网页界面:http://localhost:9090/graph。 您将看到来自YuniKorn调度程序的所有可用指标。 - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/performance_tutorial.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/performance_tutorial.md deleted file mode 100644 index 8180fa0716d..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/performance_tutorial.md +++ /dev/null @@ -1,451 +0,0 @@ ---- -id: performance_tutorial -title: 基准测试教程 -keywords: - - 性能 - - 教程 ---- - - - -## 概述 - -YuniKorn社区不断优化调度器的性能,确保YuniKorn满足大规模批处理工作负载的性能要求。 因此,社区为性能基准测试构建了一些有用的工具,可以跨版本重用。 本文档介绍了所有这些工具和运行它们的步骤。 - -## 硬件 - -请注意,性能结果因底层硬件而异。 文档中发布的所有结果只能作为参考。 我们鼓励每个人在自己的环境中运行类似的测试,以便根据您自己的硬件获得结果。 本文档仅用于演示目的。 - -本次测试中使用的服务器列表是(非常感谢[国立台中教育大学](http://www.ntcu.edu.tw/newweb/index.htm), [Kuan-Chou Lai](http://www.ntcu.edu.tw/kclai/) 为运行测试提供这些服务器): - -| 机型 | CPU | 内存 | 下载/上传(Mbps) | -| --------------------- | --- | ------ | --------------------- | -| HP | 16 | 36G | 525.74/509.86 | -| HP | 16 | 30G | 564.84/461.82 | -| HP | 16 | 30G | 431.06/511.69 | -| HP | 24 | 32G | 577.31/576.21 | -| IBM blade H22 | 16 | 38G | 432.11/4.15 | -| IBM blade H22 | 16 | 36G | 714.84/4.14 | -| IBM blade H22 | 16 | 42G | 458.38/4.13 | -| IBM blade H22 | 16 | 42G | 445.42/4.13 | -| IBM blade H22 | 16 | 32G | 400.59/4.13 | -| IBM blade H22 | 16 | 12G | 499.87/4.13 | -| IBM blade H23 | 8 | 32G | 468.51/4.14 | -| WS660T | 8 | 16G | 87.73/86.30 | -| ASUSPRO D640MB_M640SA | 4 | 8G | 92.43/93.77 | -| PRO E500 G6_WS720T | 16 | 8G | 90/87.18 | -| WS E500 G6_WS720T | 8 | 40G | 92.61/89.78 | -| E500 G5 | 8 | 8G | 91.34/85.84 | -| WS E500 G5_WS690T | 12 | 16G | 92.2/93.76 | -| WS E500 G5_WS690T | 8 | 32G | 91/89.41 | -| WS E900 G4_SW980T | 80 | 512G | 89.24/87.97 | - -每个服务器都需要执行以下步骤,否则由于用户/进程/打开文件的数量有限,大规模测试可能会失败。 - -### 1. 设置/etc/sysctl.conf -``` -kernel.pid_max=400000 -fs.inotify.max_user_instances=50000 -fs.inotify.max_user_watches=52094 -``` -### 2. 设置/etc/security/limits.conf - -``` -* soft nproc 4000000 -* hard nproc 4000000 -root soft nproc 4000000 -root hard nproc 4000000 -* soft nofile 50000 -* hard nofile 50000 -root soft nofile 50000 -root hard nofile 50000 -``` ---- - -## 部署工作流 - -在进入细节之前,这里是我们测试中使用的一般步骤: - -- [步骤 1](#Kubernetes): 正确配置Kubernetes API服务器和控制器管理器,然后添加工作节点。 -- [步骤 2](#Setup-Kubemark): 部署空pod,将模拟工作节点,命名空节点。 在所有空节点都处于就绪状态后,我们需要封锁(cordon)所有本地节点,这些本地节点是集群中的物理存在,而不是模拟节点,以避免我们将测试工作负载 pod 分配给本地节点。 -- [步骤 3](#Deploy-YuniKorn): 在主节点上使用Helm chart部署YuniKorn,并将 Deployment 缩减为 0 副本,并在`prometheus.yml`中 [修改端口](#Setup-Prometheus) 以匹配服务的端口。 -- [步骤 4](#Run-tests): 部署50k Nginx pod进行测试,API服务器将创建它们。 但是由于YuniKorn调度程序Deployment已经被缩减到0个副本,所有的Nginx pod都将停留在等待状态。 -- [步骤 5](../user_guide/troubleshooting.md#restart-the-scheduler): 将YuniKorn部署扩展回1个副本,并封锁主节点以避免YuniKorn 在那里分配Nginx pod。 在这一步中,YuniKorn将开始收集指标。 -- [步骤 6](#Collect-and-Observe-YuniKorn-metrics): 观察Prometheus UI中公开的指标。 ---- - -## 设置 Kubemark - -[Kubemark](https://github.com/kubernetes/kubernetes/tree/master/test/kubemark)是一个性能测试工具,允许用户在模拟集群上运行实验。 主要用例是可扩展性测试。 基本思想是在一个物理节点上运行数十或数百个假kubelet节点,以模拟大规模集群。 在我们的测试中,我们利用 Kubemark 在少于20个物理节点上模拟多达4K节点的集群。 - -### 1. 构建镜像 - -##### 克隆kubernetes仓库,并构建kubemark二进制文件 - -``` -git clone https://github.com/kubernetes/kubernetes.git -``` -``` -cd kubernetes -``` -``` -KUBE_BUILD_PLATFORMS=linux/amd64 make kubemark GOFLAGS=-v GOGCFLAGS="-N -l" -``` - -##### 将kubemark二进制文件复制到镜像文件夹并构建kubemark docker镜像 - -``` -cp _output/bin/kubemark cluster/images/kubemark -``` -``` -IMAGE_TAG=v1.XX.X make build -``` -完成此步骤后,您可以获得可以模拟集群节点的kubemark镜像。 您可以将其上传到Docker-Hub或仅在本地部署。 - -### 2. 安装Kubermark - -##### 创建kubemark命名空间 - -``` -kubectl create ns kubemark -``` - -##### 创建configmap - -``` -kubectl create configmap node-configmap -n kubemark --from-literal=content.type="test-cluster" -``` - -##### 创建secret - -``` -kubectl create secret generic kubeconfig --type=Opaque --namespace=kubemark --from-file=kubelet.kubeconfig={kubeconfig_file_path} --from-file=kubeproxy.kubeconfig={kubeconfig_file_path} -``` -### 3. 标签节点 - -我们需要给所有的原生节点打上标签,否则调度器可能会将空pod分配给其他模拟的空节点。 我们可以利用yaml中的节点选择器将空pod分配给本地节点。 - -``` -kubectl label node {node name} tag=tagName -``` - -### 4. 部署Kubemark - -hollow-node.yaml如下所示,我们可以配置一些参数。 - -``` -apiVersion: v1 -kind: ReplicationController -metadata: - name: hollow-node - namespace: kubemark -spec: - replicas: 2000 # 要模拟的节点数 - selector: - name: hollow-node - template: - metadata: - labels: - name: hollow-node - spec: - nodeSelector: # 利用标签分配给本地节点 - tag: tagName - initContainers: - - name: init-inotify-limit - image: docker.io/busybox:latest - imagePullPolicy: IfNotPresent - command: ['sysctl', '-w', 'fs.inotify.max_user_instances=200'] # 设置为与实际节点中的max_user_instance相同 - securityContext: - privileged: true - volumes: - - name: kubeconfig-volume - secret: - secretName: kubeconfig - - name: logs-volume - hostPath: - path: /var/log - containers: - - name: hollow-kubelet - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 4194 - - containerPort: 10250 - - containerPort: 10255 - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=kubelet - - --name=$(NODE_NAME) - - --kubeconfig=/kubeconfig/kubelet.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: - requests: # 空pod的资源,可以修改。 - cpu: 20m - memory: 50M - securityContext: - privileged: true - - name: hollow-proxy - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=proxy - - --name=$(NODE_NAME) - - --use-real-proxier=false - - --kubeconfig=/kubeconfig/kubeproxy.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: # 空pod的资源,可以修改。 - requests: - cpu: 20m - memory: 50M - tolerations: - - effect: NoExecute - key: node.kubernetes.io/unreachable - operator: Exists - - effect: NoExecute - key: node.kubernetes.io/not-ready - operator: Exists -``` - -完成编辑后,将其应用于集群: - -``` -kubectl apply -f hollow-node.yaml -``` - ---- - -## 部署 YuniKorn - -#### 使用helm安装YuniKorn - -我们可以用 Helm 安装 YuniKorn,请参考这个[文档](https://yunikorn.apache.org/docs/#install)。 我们需要根据默认配置调整一些参数。 我们建议克隆[发布仓库](https://github.com/apache/yunikorn-release)并修改`value.yaml`中的参数。 - -``` -git clone https://github.com/apache/yunikorn-release.git -cd helm-charts/yunikorn -``` - -#### 配置 - -`value.yaml`中的修改是: - -- 增加调度程序 pod 的内存/cpu 资源 -- 禁用 admission controller -- 将应用排序策略设置为 FAIR - -请参阅以下更改: - -``` -resources: - requests: - cpu: 14 - memory: 16Gi - limits: - cpu: 14 - memory: 16Gi -``` -``` -embedAdmissionController: false -``` -``` -configuration: | - partitions: - - - name: default - queues: - - name: root - submitacl: '*' - queues: - - - name: sandbox - properties: - application.sort.policy: fair -``` - -#### 使用本地版本库安装YuniKorn - -``` -Helm install yunikorn . --namespace yunikorn -``` - ---- - -## 设置Prometheus - -YuniKorn通过Prometheus公开其调度指标。 因此,我们需要设置一个Prometheus服务器来收集这些指标。 - -### 1. 下载Prometheus版本 - -``` -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` -``` -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. 配置prometheus.yml - -``` -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] - # 9080为内部端口,需要端口转发或修改9080为服务端口 -``` - -### 3. 启动Prometheus -``` -./prometheus --config.file=prometheus.yml -``` - ---- -## 运行测试 - -设置环境后,您就可以运行工作负载并收集结果了。 YuniKorn社区有一些有用的工具来运行工作负载和收集指标,更多详细信息将在此处发布。 - ---- - -## 收集和观察YuniKorn指标 - -Prometheus 启动后,可以轻松收集 YuniKorn 指标。 这是 YuniKorn 指标的[文档](metrics.md)。 YuniKorn 跟踪一些关键调度指标,这些指标衡量一些关键调度路径的延迟。 这些指标包括: - - - **scheduling_latency_seconds:** 主调度例程的延迟,以秒为单位。 - - **app_sorting_latency_seconds**: 所有应用程序排序的延迟,以秒为单位。 - - **node_sorting_latency_seconds**: 所有节点排序的延迟,以秒为单位。 - - **queue_sorting_latency_seconds**: 所有队列排序的延迟,以秒为单位。 - - **container_allocation_attempt_total**: 尝试分配容器的总次数。 尝试状态包括 `allocated`、`rejected`、`error`、`released`。 该指标仅增加。 - -您可以在Prometheus UI上轻松选择和生成图形,例如: - -![Prometheus Metrics List](./../assets/prometheus.png) - - ---- - -## 性能调优 - -### Kubernetes - -默认的 K8s 设置限制了并发请求,这限制了集群的整体吞吐量。 在本节中,我们介绍了一些需要调整的参数,以提高集群的整体吞吐量。 - -#### kubeadm - -设置pod网络掩码 - -``` -kubeadm init --pod-network-cidr=10.244.0.0/8 -``` - -#### CNI - -修改CNI掩码和资源。 - -``` - net-conf.json: | - { - "Network": "10.244.0.0/8", - "Backend": { - "Type": "vxlan" - } - } -``` -``` - resources: - requests: - cpu: "100m" - memory: "200Mi" - limits: - cpu: "100m" - memory: "200Mi" -``` - - -#### Api-Server - -在 Kubernetes API 服务器中,我们需要修改两个参数:`max-mutating-requests-inflight`和`max-requests-inflight`。 这两个参数代表API请求带宽。 因为我们会产生大量的Pod请求,所以我们需要增加这两个参数。修改`/etc/kubernetes/manifest/kube-apiserver.yaml`: - -``` ---max-mutating-requests-inflight=3000 ---max-requests-inflight=3000 -``` - -#### Controller-Manager - -在Kubernetes控制器管理器中,我们需要增加三个参数的值:`node-cidr-mask-size`、`kube-api-burst` `kube-api-qps`. `kube-api-burst`和`kube-api-qps`控制服务器端请求带宽。`node-cidr-mask-size`表示节点 CIDR。 为了扩展到数千个节点,它也需要增加。 - - -Modify `/etc/kubernetes/manifest/kube-controller-manager.yaml`: - -``` ---node-cidr-mask-size=21 //log2(集群中的最大pod数) ---kube-api-burst=3000 ---kube-api-qps=3000 -``` - -#### kubelet - -在单个工作节点中,我们可以默认运行110个pod。 但是为了获得更高的节点资源利用率,我们需要在Kubelet启动命令中添加一些参数,然后重启它。 - -修改`/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`中的起始参数,在起始参数后面添加`--max-Pods=300`并重启。 - -``` -systemctl daemon-reload -systemctl restart kubelet -``` - ---- - -## 概括 - -借助Kubemark和Prometheus,我们可以轻松运行基准测试、收集YuniKorn指标并分析性能。 这有助于我们识别调度程序中的性能瓶颈并进一步消除它们。 YuniKorn社区未来将继续改进这些工具,并继续获得更多的性能改进。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/profiling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/profiling.md deleted file mode 100644 index eb2ae74421a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/performance/profiling.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: profiling -title: 分析 ---- - - - -使用[pprof](https://github.com/google/pprof)做CPU,Memory profiling可以帮助你了解YuniKorn调度器的运行状态。YuniKorn REST服务中添加了分析工具,我们可以轻松地从HTTP端点检索和分析它们。 - -## CPU 分析 - -在这一步,确保你已经运行了YuniKorn,它可以通过`make run`命令从本地运行,也可以部署为在K8s内运行的pod。 然后运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/profile -``` - -配置文件数据将保存在本地文件系统中,一旦完成,它就会进入交互模式。 现在您可以运行分析命令,例如 - -``` -(pprof) top -Showing nodes accounting for 14380ms, 44.85% of 32060ms total -Dropped 145 nodes (cum <= 160.30ms) -Showing top 10 nodes out of 106 - flat flat% sum% cum cum% - 2130ms 6.64% 6.64% 2130ms 6.64% __tsan_read - 1950ms 6.08% 12.73% 1950ms 6.08% __tsan::MetaMap::FreeRange - 1920ms 5.99% 18.71% 1920ms 5.99% __tsan::MetaMap::GetAndLock - 1900ms 5.93% 24.64% 1900ms 5.93% racecall - 1290ms 4.02% 28.67% 1290ms 4.02% __tsan_write - 1090ms 3.40% 32.06% 3270ms 10.20% runtime.mallocgc - 1080ms 3.37% 35.43% 1080ms 3.37% __tsan_func_enter - 1020ms 3.18% 38.62% 1120ms 3.49% runtime.scanobject - 1010ms 3.15% 41.77% 1010ms 3.15% runtime.nanotime - 990ms 3.09% 44.85% 990ms 3.09% __tsan::DenseSlabAlloc::Refill -``` - -您可以键入诸如`web`或`gif`之类的命令来获得可以更好地帮助您的图表 -了解关键代码路径的整体性能。 你可以得到一些东西 -如下所示: - -![CPU Profiling](./../assets/cpu_profile.jpg) - -注意,要使用这些选项,您需要先安装虚拟化工具`graphviz`,如果您使用的是 Mac,只需运行`brew install graphviz`,更多信息请参考[这里](https://graphviz. gitlab.io/)。 - -## 内存分析 - -同样,您可以运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/heap -``` - -这将返回当前堆的快照,允许我们检查内存使用情况。 进入交互模式后,您可以运行一些有用的命令。 比如top可以列出top内存消耗的对象。 -``` -(pprof) top -Showing nodes accounting for 83.58MB, 98.82% of 84.58MB total -Showing top 10 nodes out of 86 - flat flat% sum% cum cum% - 32MB 37.84% 37.84% 32MB 37.84% github.com/apache/yunikorn-core/pkg/cache.NewClusterInfo - 16MB 18.92% 56.75% 16MB 18.92% github.com/apache/yunikorn-core/pkg/rmproxy.NewRMProxy - 16MB 18.92% 75.67% 16MB 18.92% github.com/apache/yunikorn-core/pkg/scheduler.NewScheduler - 16MB 18.92% 94.59% 16MB 18.92% github.com/apache/yunikorn-k8shim/pkg/dispatcher.init.0.func1 - 1.04MB 1.23% 95.81% 1.04MB 1.23% k8s.io/apimachinery/pkg/runtime.(*Scheme).AddKnownTypeWithName - 0.52MB 0.61% 96.43% 0.52MB 0.61% github.com/gogo/protobuf/proto.RegisterType - 0.51MB 0.61% 97.04% 0.51MB 0.61% sync.(*Map).Store - 0.50MB 0.6% 97.63% 0.50MB 0.6% regexp.onePassCopy - 0.50MB 0.59% 98.23% 0.50MB 0.59% github.com/json-iterator/go.(*Iterator).ReadString - 0.50MB 0.59% 98.82% 0.50MB 0.59% text/template/parse.(*Tree).newText -``` - -您还可以运行 `web`、`pdf` 或 `gif` 命令来获取堆图形。 - -## 下载分析样本并在本地进行分析 - -我们在调度程序docker映像中包含了基本的go/go-tool二进制文件,您应该能够进行一些基本的分析 -docker容器内的分析。 但是,如果您想深入研究一些问题,最好进行分析 -本地。 然后您需要先将示例文件复制到本地环境。 复制文件的命令如下: - -``` -kubectl cp ${SCHEDULER_POD_NAME}:${SAMPLE_PATH_IN_DOCKER_CONTAINER} ${LOCAL_COPY_PATH} -``` - -例如 - -``` -kubectl cp yunikorn-scheduler-cf8f8dd8-6szh5:/root/pprof/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -在本地环境中获取文件后,您可以运行“pprof”命令进行分析。 - -``` -go tool pprof /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -## 资源 - -* pprof 文档 https://github.com/google/pprof/tree/master/doc。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/deployment_modes.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/deployment_modes.md deleted file mode 100644 index b33e1502aa1..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/deployment_modes.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -id: deployment_modes -title: 部署模式 ---- - - - -## YuniKorn部署模式 - -YuniKorn有两种部署模式: `标准模式`与`插件模式`。 -在标准模式下,YuniKorn作为自定义模式运行Kubernetes调度程序。 -在插件模式下,YuniKorn被实现为默认Kubernetes调度框架之上的一组插件。 - -在这两种情况下,建议同时运行准入控制器(admin controller),这会确保只有一个调度程序在您的Kubernetes集群中处于活动状态。 -当准入控制器运行时,所有pod将会绕过Kubernetes的默认调度器,除了YuniKorn本身的pod。 - -## 应该使用哪个版本? - -### 标准模式(Standard) - -目前的默认模式是标准模式。 标准模式提供稳定、高效、良好性能。 -当pod利用YuniKorn的队列功能,此模式非常适合大多数此类部署。 - -### 插件模式(Plugin) - -插件模式是一种新的部署模型,调度器是在默认的Kubernetes调度逻辑之上实现的,可以更好地兼容默认的Kubernetes调度器。 -它非常适合混合工作负载,如传统的Kubernetes以及排队的应用程序。 - -插件模式目前非常新,因此还没有达到标准模式的成熟度。 - -要在使用 Helm 部署时激活插件模式,请将变量`enableSchedulerPlugin`设置为`true`。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/gang_scheduling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/gang_scheduling.md deleted file mode 100644 index 754e29c3293..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/gang_scheduling.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -id: gang_scheduling -title: 分组调度 ---- - - - -## 什么是分组调度 - -当分组调度被启用时,YuniKorn 只在以下情况下调度应用程序 -应用程序的最小资源请求能够得到满足时才会调度。否则,应用程序 -将在队列中等待。应用程序被排在层次队列中、 -启用分组调度后,每个资源队列都被分配有 -在保证最小资源的情况下,每个资源队列都被分配了最大数量的应用程序并发运行。 - -![分组调度](./../assets/gang_scheduling_intro.png) - -## 启用分组调度 - -启用分组调度不需要在集群范围内进行配置。 -调度器会主动监控每个应用的元数据,如果该应用包含了 -一个有效的任务组定义,它就会被认为是所需的分组调度。 - -:::info 任务组 -一个任务组是一个应用程序中的任务 "群组",这些任务具有相同的资源概况 -和相同的放置限制。它们被认为是同质化的请求,在调度器中可以被视为 -在调度器中被当作同一类请求处理。 -::: - -### 前提 - -对于运行支持调度的应用程序的队列,队列排序策略应该被设置为 "FIFO"。 -要配置队列排序策略,请参考文档:[应用程序排序](user_guide/sorting_policies.md#应用程序排序)。 - -#### 为什么要使用 "FIFO" 排序策略? - -当分组调度被启用时,调度器会主动为每个应用程序保留资源。 -如果队列排序策略不是基于FIFO(StateAware 是基于 FIFO 的排序策略)、 -调度器可能会为每个应用保留部分资源并导致资源分割问题。 - -#### "StateAware" 排序策略的副作用 - -我们不建议使用 `StateAware`,尽管它是一个基于 FIFO 的策略。第一个 pod 的失败或者该 pod 的初始化时间过长都会使处理过程变慢。 -当驱动在请求执行器之前进行大量的预处理时,尤其是 Spark。 -在这些情况下,`StateAware` 超时会使处理速度减慢到每次超时只有一个应用程序。 -这实际上会推翻群组的保留,并导致减速和过度使用资源。 - -### 应用程序配置 - -在 Kubernetes 上,YuniKorn 通过从单个pod加载元数据来发现应用,应用的第一个pod -被要求附上一份完整的应用元数据副本。如果应用程序没有关于第一个或第二个pod的任何注释, -那么所有的pod都需要携带相同的 taskGroups 信息。分组調度需要 taskGroups 的定义, -可以通过 pod 注解来指定。所需的字段是: - -| 注释 | 价值 | -|-----|------| -| yunikorn.apache.org/task-group-name | 任务组名称,在应用程序中必须是唯一的。 | -| yunikorn.apache.org/task-groups | 任务组的列表,每一项都包含了为该任务组定义的所有信息。 | -| yunikorn.apache.org/schedulingPolicyParameters | 可选。一个任意的键值对来定义调度策略参数。请阅读[调度策略参数](#调度策略参数) | - -#### 需要多少个任务组? - -这取决于这个应用程序向 K8s 请求多少不同类型的 pod。一个任务组是一个应用程序中的任务 "群组"、 -这些任务具有相同的资源概况和相同的放置限制。它们被认为是同质的 -在调度器中可以被视为同类的请求。以 Spark 为例,每个作业都需要有2个任务组、 -一个用于driver pod,另一个用于 executor pods。 - -#### 如何定义任务组? - -任务组的定义是应用程序的真实pod定义的副本,像资源、节点选择器、容忍度 -和亲和力应该与真正的pod相同。这是为了确保调度器能够以准确的pod规格保留资源。 -确切正确的pod规范。 - -#### 调度策略参数 - -调度策略相关的可配置参数。在pod的注释中以下列格式应用这些参数: - -```yaml -annotations: - yunikorn.apache.org/schedulingPolicyParameters: "PARAM1=VALUE1 PARAM2=VALUE2 ..." -``` - -目前,支持以下参数: - -`placeholderTimeoutInSeconds` - -默认值: *15分钟*。 -这个参数定义了预约超时,即调度器在放弃分配所有占位符之前应该等待多长时间。 -当调度器*分配第一个占位器pod*时,超时计时器开始计时。这确保了如果调度器 -无法调度所有的占位荚,它最终会在一定的时间后放弃。这样,资源可以被 -释放出来,供其他应用程序使用。如果没有占位符可以被分配,这个超时就不会启动。为了避免占位符 -pods永远卡住,请参考 [故障排除](troubleshooting.md#成组调度) 了解解决方案。 - -`gangSchedulingStyle` - -有效值: *Soft*, *Hard* - -默认值:*Soft*. -这个参数定义了当应用程序由于占位符 pod 分配而遇到分组问题时的后退机制。 -更多细节见[分组调度风格](#分组调度风格)部分 - -更多的调度参数将被添加,以便在调度应用程序时提供更多的灵活性。 - -#### 示例 - -下面的例子是一个工作的yaml文件。这个工作启动了2个 pod,每个 pod 睡眠时间为 30 秒。 -在 pod 规范中值得注意的变化是 *spec.template.metadata.annotations*,在这里我们定义了 `yunikorn.apache.org/task-group-name -和 `yunikorn.apache.org/task-groups` 。 - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-scheduling-job-example -spec: - completions: 2 - parallelism: 2 - template: - metadata: - labels: - app: sleep - applicationId: "gang-scheduling-job-example" - queue: root.sandbox - annotations: - yunikorn.apache.org/task-group-name: task-group-example - yunikorn.apache.org/task-groups: |- - [{ - "name": "task-group-example", - "minMember": 2, - "minResource": { - "cpu": "100m", - "memory": "50M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "50M" -``` - -当这项工作提交给 Kubernetes 时,将使用同一模板创建2个pod,它们都属于一个任务组: -*"task-group-example"*。 YuniKorn将创建2个占位符pod,每个都使用任务组定义中指定的资源。 -当所有2个占位符分配完毕后,调度器将使用占位符保留的位置来绑定真正的2个睡眠pods。 - -如果有必要,你可以添加多个任务组,每个任务组由任务组名称标识、 -通过设置任务组名称,需要将每个真实的pod与一个预先定义的任务组进行映射。注意、 -任务组名称只要求在一个应用程序中是唯一的。 - - -### 启用Spark作业的Gang调度 - -每个Spark作业都运行2种类型的pod,驱动和执行器。因此,我们需要为每个作业定义2个任务组。 -驱动器pod的注释看起来像: - -```yaml -Annotations: - yunikorn.apache.org/schedulingPolicyParameters: “placeholderTimeoutSeconds=30” - yunikorn.apache.org/taskGroupName: “spark-driver” - yunikorn.apache.org/taskGroup: “ - TaskGroups: [ - { - Name: “spark-driver”, - minMember: 1, - minResource: { - Cpu: 1, - Memory: 2Gi - }, - Node-selector: ..., - Tolerations: ..., - Affinity: ... - }, - { - Name: “spark-executor”, - minMember: 10, - minResource: { - Cpu: 1, - Memory: 2Gi - } - } - ] - ” -``` - -:::note -任务组的资源必须考虑到Spark驱动和执行器的内存开销。 -参见 [Spark documentation](https://spark.apache.org/docs/latest/configuration.html#application-properties) 以了解如何计算这些数值的细节。 -::: - -对于所有的执行者 pod, - -```yaml -Annotations: - # 任务组字段中定义的名称相匹配 - # 在任务组字段中定义 - yunikorn.apache.org/taskGroupName: “spark-executor” -``` - -一旦工作被提交给调度器,工作就不会被立即调度。 -相反,在实际启动驱动/执行器之前,调度器将确保它获得最小的资源。 - -## 分组调度风格 - -有2种分组调度方式支持,分别是 Soft 和 Hard。它可以在每个应用层面进行配置,以定义应用在分组调度失败时的行为。 - -- `Hard Style`:当使用这种风格时,我们将有初始行为,更确切地说,如果应用程序不能根据分组调度规则进行调度,并且超时,它将被标记为失败,而不会重新尝试调度。 -- `Soft Style`:当应用程序不能被分组调度时,它将退回到正常的调度,并使用非分组调度策略来实现最佳努力的调度。当这种情况发生时,应用程序将过渡到恢复状态,所有剩余的占位符 pod 将被清理掉。 - -**使用的默认样式**: ``Soft。 - -**启用一个特定的风格**:可以通过在应用程序定义中设置'gangSchedulingStyle'参数来改变风格,即 Soft 或 Hard。 - -#### Example - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-app-timeout -spec: - completions: 4 - parallelism: 4 - template: - metadata: - labels: - app: sleep - applicationId: gang-app-timeout - queue: fifo - annotations: - yunikorn.apache.org/task-group-name: sched-style - yunikorn.apache.org/schedulingPolicyParameters: "placeholderTimeoutInSeconds=60 gangSchedulingStyle=Hard" - yunikorn.apache.org/task-groups: |- - [{ - "name": "sched-style", - "minMember": 4, - "minResource": { - "cpu": "1", - "memory": "1000M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - imagePullPolicy: "IfNotPresent" - command: ["sleep", "30"] - resources: - requests: - cpu: "1" - memory: "1000M" - -``` - -## 验证配置 - -为了验证配置是否已经完全正确,请检查以下事项: -1. 当一个应用程序被提交时,验证预期的占位符数量是否被调度器创建。 -如果你定义了两个任务组,一个是minMember 1,另一个是minMember 5,这意味着我们期望在任务提交后有6个占位符被创建。 -被创建。 -2. 验证占位符的规格是否正确。每个占位符都需要有与同一任务组中的真实pod相同的信息。 -检查领域包括:命名空间、pod资源、节点选择器、容忍度和亲和力。 -3. 验证占位符可以分配到正确的节点类型上,并验证真正的pod是通过替换占位符pod而启动的。 - -## 故障排除 - -请参阅启用帮派调度时的故障排除文档 [這裡](troubleshooting.md#成组调度) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/placement_rules.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/placement_rules.md deleted file mode 100644 index 17ccd279c87..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/placement_rules.md +++ /dev/null @@ -1,296 +0,0 @@ ---- -id: placement_rules -title: App 放置规则 ---- - - -基础的放置规则(placement rules)配置[调度弃配置设计文档](../design/scheduler_configuration#placement-rules-definition)中有相关描述。 - -我们可以将多个规则链结再一起形成一个放置策略,并通过[存取控制列表(Access control lists)](user_guide/acls.md)和规则过滤来定义和执行规则。 - -本篇文章将通过例子来解释如何建立策略以及规则的使用,而该放置策略为调度器的一部分。 - -## 配置 -放置规则作为调度程序队列配置的一部分,可以在各分区(partition)中被定义。规则定义的顺序就是他们会被执行的顺序。如果一个规则匹配,策略会停止执行剩余的规则。 - -匹配的放置规则会产生一个完全合格的队列名称。同时这个回传的队列名称会从根队列(root)开始。而在队列层次结构中,可以生成的层次数量没有限制。 - -当要执行一条规则时,已经被执行过的规则不会被列入考虑;这条规则也不会对往后要执行的规则有所影响:规则不能影响其他的规则,除非它们被配置为父规则([parent](#parent-参数))。 - -当放置策略没有生成队列名称且没有更多的规则时,应用程式将会被拒绝。 - -在配置中,定义放置规则的基本结构如下: -```yaml -placementrules: - - name: <第一条放置规则的名称> - - name: <第二条放置规则的名称> -``` -每个[规则](#规则)都可以在配置中采取一套预定义的参数。可以被使用的规则名称在规则描述中提及。规则名称在配置中不区分大小写,且必须遵从以下的命名惯例: -* 从字母开始:a-z 或 A-Z -* 后面跟着0或多个字元 a-z, A-Z, 0-9 或 _ - -当规则名称没有对应到任何已定义的规则时,表示规则处于未知的状态,会造成放置管理器初始化错误。如果参数不正确,会抛出解析错误或在初始化时发生错误。一个有错误的规则集永远不可能被激活。 - -如果放置管理器中含有一个被激活的规则集,就代表他已经初始化了。重新载入时,若配置了一个新的规则集时,就会将新的规则集激活,并取代旧有的。如果新规则集包含一个错误,放置管理器就会忽视这个新规则集,同时也持续处于「使用不完全的规则集」的状态。如果放置管理器持续使用已激活的规则集,忽视新的且有错误的规则集时,则会记录一条关于坏掉且被忽视的配置信息。 - -规则结果中的「点 "."」,会被文字的「"\_dot\_"」所替代。而「点」会被取代是因为在完全限定的队列名称中,他是被用来分隔队列层次的。而替代过程是发生在建构完整队列层次,且结果合格之前。这代表我们允许用「点」来表达用户名或标籤值,但不影响到队列层次。举例来说,当配置中的队列对应到「含有点的用户名」时,你必须要使用以下方法来指定它们:如果一个用户名称为`user.name`且使用`user`规则,则会产生队列名称为`root.user_dot_name`的队列。而如果该用户队列必须事先被加到配置中,则也该使用`user_dot_name`这个名字。 - -### Create 参数 -create 参数是一个布林值,会定义当一个队列不存在时,是否可以在规则的定义下创建队列。不能保证队列一定会被创建,因为现有的队列可能会阻止创建。但如果规则定义下想创建的队列不存在,且`create: false`,那结果将会是创建失败。 - -带有`create`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - create: true -``` -预设值为`false`。允许的值为`true`或`false`,其他值均会导致显示错误。 - -### Parent 参数 -`parent` 参数允许指定一个规则,并为他产生一个父队列。父规则可以被嵌套,一个父规则可以包含另一个父规则,此外对于父规则的嵌套也没有强制限制。 - -父规则被视为顶层的规则,因此具有与放置定义中任何其他规则相同的参数和需求。例外的情况是,在「已经生成完全合格队列」的规则上再使用父规则,被认为是一个配置错误。这个错误只能发生在`fixed`型的规则上,查看规范可以得到更多细节。 - -注意:规则的执行会沿着父规则的列表向下遍历,并首先执行列表中的最后一条。代表最后一条父规则将会直接产生在根部,详见示例。 - -带有`parent`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - parent: - name: <父规则的名称> -``` -预设值中没有parent参数。 - -### Filter 参数 -通过`filter`参数的定义,能过滤掉适用的用户来进行配置。过滤器是一个复杂的配置組件。 - -用户和群组可以被配置为两种类别: -* 正则表达式 -* 用户或群组的列表 - -如果用户或群组在yaml中的条目超过一个,则就会被视为一个用户列表或群组列表。列表中重复的条目会被忽略,不会引起错误。依据其他列表元素来使用正则表达式是不被允许的。 - -用户和群组名称遵循标准的Linux 用户和群组惯例,对于用户名来说: -* 从一个字母作为开头:a-z 或 A-Z -* 后面跟着0或更多个字符:a-z, A-Z, 0-9 或 _ . @ - -* 最后一个字符可以式$ - -对于群组名来说: -* 从一个字母作为开头:a-z 或 A-Z -* 后面跟着0或更多个字符:a-z, A-Z, 0-9 或 _ - - -如果列表中正好有一个条目,他可以是单个用户、群组或正则表达式。当一个条目包含一个在用户或群组中不允许的字符时,该条目会被认为是一个正则表达式。正则表达式必须按照规定进行编译。一个不能编译的正则表达式将会被忽略。 - -此外针对群组的正则表达式中:每次都是针对一个组进行匹配,而不是针对组的列表。 - -带有 `filter`参数的简易yaml范例: -```yaml -filter: - type: deny - users: - - - - - groups: - - - - -``` -预设值中没有filter参数。 - -### Value 参数 -这是一个通用值,用来传递给规则以实现或改变其行为。该值被用来与[fixed](#fixed-rule)和[tag](#tag-rule)型的规则一起使用。此外`value`是以字串型式存在的单一值,也不会被系统解释或干扰。 - -带有 `value`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - value: "any string" -``` -预设值中没有value参数。 - -## 准入控制列表 -准入控制列表没有在规则中定义,但它们影响放置策略的结果。有两种准入控制列表可以被定义到队列上: -1. 提交ACL: `submitacl` -2. 管理ACL: `adminacl` - -如果队列的ACL允许任何ACL提交存取,则放置规则才能匹配。管理队列ACL还提供「提交准入」的功能。如果队列不存在或没有配置ACL,则将检查父队列的ACL。这种递迴的检查会重复执行,直到有ACL提供存取或根目录的ACL被检查过后。 - -关于ACL语法的更多细节,请查阅[ACL文档](user_guide/acls.md)。 - -## 规则 -### Provided Rule -在配置中使用的名称:*provided* - -提供在提交应用时所指定的队列。本规则的行为是─如果队列不完全合格,则完全限定由「应用程序提供的队列」作为放置的队列。如果设置了一个父规则,并且在应用程序提交中提供的队列是完全合格的,那麽父规则就不会被执行。 - -支持的参数: -* create -* parent -* filter - -举例:如果用户名下不存在队列,则用户传入的队列会被创建。 -```yaml -placementrules: - - name: provided - create: true - parent: - name: user - create: true -``` -当用户 `developer` 向应用程式提交请求,且应用程式要求的队列名称为:`my_special_queue`。
-结果:`root.developer.my_special_queue`(父规则将设置用户名称)。 - -当用户 `developer` 向应用程式提交请求,且应用程式要求的队列名称为:`root.dev_queue`。
-结果:`root.dev_queue`(父规则将被忽视)。 - -### User Name Rule -在配置中使用的名称:*user* - -提供一个基于用户名的队列,而该用户名为所提交的应用程序的一部分。 - -支持的参数: -* create -* parent -* filter - -举例:提交一个基于用户名的队列,如果队列不存在,不要创建队列。 -```yaml -placementrules: - - name: user - create: false -``` - -当用户`finance.test`提交了一个应用程式,此外对应的队列也存在。
-结果: `root.finance_dot_test`(注意,「点」被替换了)。 - -当用户`developer`提交了一个应用程式,但对映的队列不存在。
-结果:失败,执行下一条规则。 - -### Fixed Rule -在配置中使用的名称:*fixed* - -回传一个队列,其依据规则参数的值作为名称,配置的值必须是一个合法的队列名称或层次结构。该队列名称不一定需要完全合格。名称中的层次结构使用「一个点(.)」作为层次结构中不同级别的分隔符。只有当配置的队列不存在且`create`标籤未设置时,`fixed`规则才会失败,因为他始终新增一个配置的队列。 - -支持的参数: -* value(reuqired) -* create -* parent -* filter - -举例:因为总是会回传一个队列,若没有设置`create`标籤,则要在配置中将队列定义为子队列。 -```yaml -placementrules: - - name: fixed - value: last_resort -``` - -当用户 `developer`提交请求,且在应用程式中设定的队列为:`my_special_queue` 。
-结果:`root.last_resort`。 - -### Tag Rule -在配置中使用的名称:*tag* - -从应用程式的标籤中检索队列名称。检查`tag`的值(value),并在规则中使用该值进行配置。若`tag`规则没有包含任何值,则代表配置错误,但是一个应用程式不一定要设置该值。 - -如果应用程序上没有设置对应的`tag`,则规则失败。如果从应用程序回传的`tag` value是一个完全限定的队列名称,则父规则(如果已配置)将不会执行。 - -支持的参数: -* value(reuqired) -* create -* parent -* filter - -举例:根据kubernetes命名空间放置一个应用程序,该命名空间在提交时自动在应用程序中设置。 -```yaml -placementrules: - - name: tag - value: namespace - create: true -``` - -用户`developer`在命名空间`default`,提交基于kubernetes的应用程序请求,且在应用程是中设定的队列为:`my_pecial_queue`。
-结果:`root.default`。 - -用户`developer`在命名空间`testing`,提交基于kubernetes的应用程序请求,且在应用程是中设定的队列为:`my_pecial_queue`。
-结果:`root.testing`。 - -用户提交非基于kubernetes的应用程序请求。
-结果:失败,执行下一条规则。 - -## 复杂的例子 -在这个复杂的例子中,我们串连了三个规则: - -1. 一个`user`规则,其父规则标籤使用kubernetes命名空间,且仅供`dev`群组内的用户。 -2. 一个`tag`规则,使用kubernetes命名空间,其`parent`规则固定使用已存在的队列─ `root.namespaces`。 -3. 一个`fixed`规则,将所有到达这个点的应用程序都放在`root.default`队列中。 - -举例: -```yaml -placementrules: - - name: user - create: true - filter: - type: allow - groups: - - dev* - parent: - - name: tag - value: namespace - - name: tag - value: namespace - create: true - parent: - - name: fixed - value: root.namespaces - filter: - type: allow - users: - - john - - name: fixed - value: root.default -``` -用户`john`在命名空间testing中提交基于kubernetes应用程序的请求。
-结果:`root.namespaces.testing`(在规则2中匹配)。 - -用户`sarah`在命名空间`newapp`中提交基于kubernetes应用程序的请求,组员为`sarah`, `test_app`, `dev_app`。
-结果:`root.newapp.sarah`(在规则1中匹配)。 - -用户bob在命名空间`testapp`中提交基于kubernetes应用程序的请求,组别成员为`bob`。
-结果:`root.default`(在规则3中匹配)。 -
-在第二个例子中,我们使用了两条规则。 - -1. 一个`fixed`规则,将所有东西放在`root.production`队列中。 -2. 一个`user`规则,以及设置 `create` 标籤。 - -但在这个例子中,我们在`root.production`的队列上设置了ACL,只允许两个特定的用户使用这个队列。因此,即使规则匹配,除非是`john`或`bob`,否则应用程式将不会被放在`production`队列中。所有其他用户将匹配第二条规则并使用它们自己的队列,如果队列不存在,就会创建。 - -```yaml -partitions: - - name: default - queues: - - name: production - submitacl: john,bob - placementrules: - - name: fixed - value: root.production - - name: user - create: true -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/prometheus.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/prometheus.md deleted file mode 100644 index 4ded82ff1f1..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/prometheus.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: prometheus -title: Setting Prometheus ---- - - - -YuniKorn exposes its scheduling metrics via Prometheus. Thus, we need to set up a Prometheus server to collect these metrics. - -If you don't know what metric can be used, you can use [REST API](../api/scheduler.md#指标(Metrics)). - -### 1. **Download Prometheus release** - -```bash -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` - -```bash -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. **Configure prometheus.yml** - -Prometheus collects metrics from *targets* by scraping metrics HTTP endpoints. - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['localhost:9080'] - # 9080 is internal port, need port forward or modify 9080 to service's port -``` - -### 3. Start port-forward - -Port forwarding for the core's web service on the standard port can be turned on via: - -```bash -kubectl port-forward svc/yunikorn-service 9080:9080 -n yunikorn -``` - -`9080`is the default port for core's web service. - -### 4. Execute prometheus - -```bash -./prometheus --config.file=prometheus.yml -``` - -![prometheus-cmd](../assets/prometheus-cmd.png) - -### 5. Access the Prometheus UI - -You should be able to browse to a status page at [localhost:9090](http://localhost:9090/). Give it a couple of seconds to collect data about itself from its own HTTP metrics endpoint. - -![prometheus-web-ui](../assets/prometheus-web-ui.png) - -You can also verify that Prometheus is serving metrics by navigating to its metrics endpoint:[localhost:9090/metrics](http://localhost:9090/metrics) \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/queue_config.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/queue_config.md deleted file mode 100644 index c8a140eba35..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/queue_config.md +++ /dev/null @@ -1,382 +0,0 @@ ---- -id: queue_config -title: 分区和队列配置 ---- - - - -队列配置基础在[配置设计文档](design/scheduler_configuration.md)中有描述。 - -本文档提供通用队列配置。 -队列配置引用了[访问控制列表](user_guide/acls.md)和[放置规则](user_guide/placement_rules.md)文档。 - -本文档通过示例说明如何为调度程序创建分区和队列配置。 - -调度程序依靠shim可靠地提供用户信息作为应用程序提交的一部分。 -当前shim使用[用户和组解析](usergroup_resolution)中提供的方法识别用户和用户所属的组。 - -## 配置 -此处描述的调度器的配置文件仅提供分区和队列的配置。 - -默认情况下,我们在部署中使用`queues.yaml`文件。 -文件名可以通过命令行更改调度器的`policyGroup`标志。 -更改文件名后必须对部署细节进行相应的更改,可以是`configmap`或包含在docker容器中的文件。 -配置的示例文件位于yunikorn-core的[queues.yaml](https://github.com/apache/yunikorn-core/blob/master/config/queues.yaml). - -## 分区 -分区(partitions)是调度器配置的最高级别。 -在配置中可以定义多个分区。 - -配置中分区定义的基本结构如下: -```yaml -partitions: - - name: <第一个分区的名称> - - name: <第二个分区的名称> -``` -分区的默认名称是`default`。 -分区定义包含特定shim相应调度器的完整配置。 -每个shim都使用自己独特的分区。 - -分区必须至少需要定义以下键: -* name -* [queues](#队列) - -队列配置会在分区结束后介绍。 - -可以选择为分区定义以下键: -* [placementrules](#放置规则) -* [statedumpfilepath](#状态转储文件路径) -* [limits](#限制) -* nodesortpolicy -* preemption - -放置规则和限制在各自的章节中解释。 - -`nodesortpolicy`定义节点为分区排序的方式。 -有关可以使用的节点排序策略值的详细信息,请参阅[排序策略](user_guide/sorting_policies.md#node-sorting)文档。 - -抢占键目前只能有一个子键: _enabled_。 -这个布林值定义了整个分区的抢占行为。 - -_enabled_的默认值为_false_。 -_enabled_的允许值:_true_或_false_,任何其他值都会导致解析错误。 - -下方的示例中,`partition` yaml条目是带有_preemption_标志集和_fair_的`nodesortpolicy`。 -```yaml -partitions: - - name: <分区名称> - nodesortpolicy: fair - preemption: - enabled: true -``` -备注: -目前,Kubernetes独特的shim不支持除`default`分区之外的任何其他分区。 -这已被记录为shim的[jira](https://issues.apache.org/jira/browse/YUNIKORN-22)。 - -### 队列 - -YuniKorn通过利用资源队列来管理资源。 -资源队列(queues)具有以下特征: -- 队列可以有**层次**结构 -- 每个队列都可以预设**最小/最大容量**,其中最小容量定义保证资源,最大容量定义资源限制(所谓的资源配额) -- 任务必须在某个`leaf`队列下运行 -- 队列可以是**静态**(从配置文件加载)或**动态**(由YuniKorn内部管理) -- 队列级别的**资源公平**是由调度器强制执行 -- 作业只能在特定队列下运行 - -:::info -YuniKorn队列与[Kubernetes命名空间](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)的区别: -Kubernetes命名空间提供了Kubernetes资源的范围,包括安全环境(即谁可以访问对象),以及定义[资源配额](https://kubernetes.io/docs/concepts/policy/resource-quotas/)时的资源边界(即对象可以使用多少资源)。 -另一方面,YuniKorn队列仅使用一组作业可以使用多少资源,以及以何种顺序使用。 -YuniKorn队列在考虑资源公平性、作业排序等方面提供了更细粒度的多租户资源共享控制。 -在大多数情况下,YuniKorn队列可用于替代命名空间资源配额,以提供更多的调度特性。 -::: - -_queues_条目是主要的配置元素,它为队列定义了层次结构。 - -它可以定义一个`root`队列,但它不是必需的元素。 -如果未定义`root`队列,配置解析将插入root队列以保持一致性。 -以下因素会触发root队列的插入: -* 如果配置在顶层定义了多个队列,则会插入一个根队列。 -* 如果在顶层只定义了一个队列并且它不被称为`root`,则插入一个root队列。 - -定义的一个或多个队列将成为插入的`root`队列的子队列。 - -带有子队列的基本`queue` yaml条目: -```yaml -queues: -- name: <队列名称> - queues: - - name: <队列名称> -``` - -队列支持的参数: -* name -* parent -* queues -* maxapplications -* properties -* adminacl -* submitacl -* [resources](#资源) -* [limits](#限制) - -每个队列都必须有一个_name_并且队列的名称在定义队列的同一级别上必须是唯一的。 -由于队列结构是完全层次化的,层次结构中不同点的队列可能具有相同的名称。 -例如:队列结构`root.testqueue`和`root.parent.testqueue`是一个有效的结构。 -需注意的是,队列不能包含点“.”字符,因为该字符用于分隔层次结构中的队列。 -如果名称对于配置中的队列不是唯一的,或者名称包含一个点,则会生成解析错误并拒绝配置。 - -依队列的类型是否于队列有子模板队列和子队列的事实,结构中的队列将自动获得分配的类型。 -队列类型有两种: -* parent -* leaf - -应用只能分配给_leaf_队列。 -在配置中,队列具有子模板队列或子队列将自动成为_parent_队列。 -如果队列在配置中没有子队列,则该队列是_leaf_队列,除非该队列`parent`参数设置为_true_。 -尝试覆盖配置中的_parent_队列类型将导致配置解析错误。 - -parent队列的子队列在`queues`条目下定义。 -`queues`条目是队列级别的递归条目,它使用完全相同的参数集。 -_maxapplications_属性是一个大于 1 的整数值,它允许您限制队列中正在运行的应用的数量。 -不允许为_maxapplications_指定零,因为它会阻止队列中应用的任何分配。 -_子_队列的_maxapplications_值必须小于或等于_parent_队列的值。 -`properties`参数是一个简单的键值对列表,并为队列提供一组简单的属性。其中的键或值没有限制,任何东西都是允许的。 -目前,属性列表仅在调度器中用于定义leaf队列的[排序顺序](user_guide/sorting_policies.md#application-sorting)。 -在未来的扩展中,添加比如打开或关闭队列抢占或其他排序策略的选项,让使用相同的属性构造而无需更改配置。 - -通过`adminacl`设置对队列的访问权限以进行管理操作,并通过`submitacl`条目提交应用。 -访问控制列表(ACLs)的描述可见[访问控制列表(ACLs)](user_guide/acls.md)文档。 - -队列资源限制是通过`resources`参数设置。 -用户和群组的限制是通过`limits`参数设置。 -由于这两个条目都是复杂的配置条目,因此它们在下面的[resources](#资源)和[limits](#限制)中有相应解释。 - -以下示例配置是`root.namespaces`队列作为具有限制的_parent_队列: -```yaml -partitions: - - name: default - queues: - - name: namespaces - parent: true - maxapplications: 12 - resources: - guaranteed: - {memory: 1G, vcore: 10} - max: - {memory: 10G, vcore: 100} - queues: - - name: level1 - maxapplications: 8 - resources: - guaranteed: - {memory: 0.5G, vcore: 5} - max: - {memory: 5G, vcore: 50} -``` - -### 放置规则 - -放置规则(placement rules)在[放置规则](user_guide/placement_rules.md)文档中有相关定义和记录。 - -每个分区只能定义一组放置规则。 -如果没有定义规则,则放置管理器不会启动。 -此外,在提交应用时,*必须*为每个应用设置一个队列。 - -### 状态转储文件路径 - -状态转储文件路径(Statedump filepath)定义YuniKorn状态转储的输出文件并且它可以在分区级别上设置。 -如果设置转储文件路径,该字段的值可以是相对路径或绝对路径(此处相对路径是基于工作目录)。 -如果YuniKorn调度器没有足够的权限在指定路径创建状态转储文件,它将无法启动状态转储的功能。 - -```yaml -statedumpfilepath: -``` -如果上面的键没有在分区配置中指定,它的默认值为`yunikorn-state.txt`。 -需注意的是,如果键在多个分区中指定,则其第一次出现的值优先。 - -状态转储文件也有一个固定的循环策略。 -目前,每个状态转储文件的容量为10MB,最多可以有10个这样的文件。 -当前正在写入的状态转储文件将始终是上面配置的值或默认的`yunikorn-state.txt`。 -当达到文件大小限制时,日志旋转器(`lumberjack`)将通过在文件前加上时间戳来修改文件,并创建一个具有相同的无前缀名称的新文件来写入状态转储。 -如果达到状态转储文件的最大数量,轮换策略将删除根据标记时间戳的最旧文件。 - -### 限制 -限制(limits)为分区或队列定义一组限制对象,以及它可以在分区或任何级别的队列上设置。 -```yaml -limits: - - limit: <描述> - - limit: <描述> -``` - -限制对象是一个复杂的配置对象,它为一组用户和/或群组定义一个限制。 -多个独立的限制可以设置为队列或分区上一个`limits`条目的一部分。 -不属于限制设置的用户和/或群组将不受限制。 - -limits条目的示例: -```yaml -limits: - - limit: <描述> - users: - - <用户名或"*"> - - <用户名> - groups: - - <群组名称或"*"> - - <群组名称> - maxapplications: <1..最大值> - maxresources: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] -``` - -队列限制的情况下,应用递归限制。 -这意味着对`root`队列的限制是集群中用户或群组的总体限制。 -因此,`root`队列限制也等同于`partition`限制。 - -limits参数: -* limit -* users -* groups -* maxapplications -* maxresources - -_limit_参数是limits条目的可选描述。 -除了使配置易于理解和可读之外,它不用于任何其他用途。 - -可以配置的_users_和_groups_可以是以下两种类型之一: -* 一个星号字符 "*" -* users或groups的列表。 - -如果users或groups的条目包含超过1个条目,则它始终被视为users或groups的列表。 -星号字符“*”为通配符,匹配所有用户或群组。 -不允许在其他列表元素旁边指定星号字符。 -列表中的重复条目将被忽略,并不会导致解析错误。 - -_maxapplications_是一个无符号整数值。 -当_maxapplications_大于1,它允许您限制为配置的用户或群组运行的应用的数量。 -不允许指定_maxapplications_为0,因为_maxapplications_为0时,隐含拒绝任何访问。 -拒绝访问的规范应交由ACL条目处理。 - -_maxresources_参数可用于指定一个或多个资源的限制。 -_maxresources_使用与队列的[resources](#资源)参数相同的语法。 -未在列表中指定的资源不受限制。 -资源限制可以设置为 0,这可以防止用户或群组请求指定的资源,即使队列或分区具有可用的特定资源也是如此。 -不允许将总体资源限制指定为零,换言之,这意味着限制中指定的至少一个资源必须大于零。 -如果资源在队列上不可用,则应使用队列定义上的最大资源。 -指定一个实际上为零的限制,_maxapplications_ 为零并且所有资源限制为零,这是不允许的,并且会导致解析错误。 - -每个用户或群组都有一个限制,它*不是*所有用户或群组的组合限制。 - -举个例子: -```yaml -limit: "example entry" -maxapplications: 10 -users: -- sue -- bob -``` -在这种情况下,用户`sue`和`bob`都被允许运行10个应用。 - -### 资源 -队列的resources条目可以为队列设置_guaranteed_和/或_maximum_资源,yunikorn会递归地检查资源限制。 -leaf队列的资源使用量是为该队列分配的所有资源的总和。 -parent队列的资源使用量是该parent队列下面所有队列,leaf和parent队列的资源使用量的总和。 - -root队列没有_guaranteed_的资源设置。 -root队列的_max_资源限制自动等于集群大小。 -如果root队列设置了任何限制,则会发生解析错误。 -leaf队列在定义时不能设置任何资源限制。 - -配置后的_max_资源对可以在任何时间点分配给队列的所有分配的大小进行了硬性限制。 -_max_资源可以设置为0,这使得资源对队列不可用。 -_guaranteed_资源用于计算队列份额和分配期间,它用作决定将分配分配给哪个队列的输入之一。 -抢占使用队列的_guaranteed_资源作为队列不能低于的基础。 - -基本的`resources` yaml条目: -```yaml -resources: - guaranteed: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] - max: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] -``` -列表中未指定的资源不受限制,对于最大(max)资源,或在保证(guaranteed)资源的情况下保证。 - -可以为资源数量指定一个可选的后缀。 -有效的国际单位制后缀是`k`、`M`、`G`、`T`、`P` 和 `E`,用于10的幂,以及`Ki`、`Mi`、`Gi`、`Ti`、 `Pi`和`Ei`表示2的幂。 -此外,`vcore`类型的资源可能带有后缀`m`以表示millicores。 例如,`500m`是vcore的50%。 -默认情况下,`memory`类型的单位以byte为单位进行解释。 -所有其他资源类型都没有指定的基本单位。 - -注意,以上单位行为从yunikorn 1.0开始有效 -以前的版本将`memory`解释为1000000(百万)bytes的单位,将`vcore`解释为millicores。 - -### 子模板 - -子模板(child template)可以在父类型队列的队列层次结构中的任何级别来定义。 -parent队列可以提供一个模板来定义它下面的动态leaf队列的行为。 -如果parent队列定义了子模板,则没有子模板的parent队列会从其parent队列继承子模板。 - -模板中支持的配置如下所示。 -1. application sort policy -2. max resources -3. guaranteed resources -4. max applications - -举个例子: -```yaml - partitions: - - name: default - placementrules: - - name: provided - create: true - queues: - - name: root - submitacl: '*' - childtemplate: - maxapplications: 10 - properties: - application.sort.policy: stateaware - resources: - guaranteed: - vcore: 1 - memory: 1G - max: - vcore: 20 - memory: 600G - queues: - - name: parent - parent: true - childtemplate: - resources: - max: - vcore: 21 - memory: 610G - - name: notemplate - parent: true -``` -在这种情况下,`root.parent.sales`将直接使用parent队列`root.parent`的子模板。 -相比之下,`root.notemplate.sales`将使用在队列`root`上设置的子模板,因为其parent队列 `root.notemplate` 从队列`root`继承了子模板。 - -[已弃用] 如果您的集群依赖于动态叶队列可以从父级继承`application.sort.policy`的旧行为(由[YUNIKORN-195](https://issues.apache.org/jira/browse/YUNIKORN-195)引入),请迁移到模板。 -旧的行为将在未来的版本中被删除。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/resource_quota_mgmt.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/resource_quota_mgmt.md deleted file mode 100644 index 6d0811a3a36..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/resource_quota_mgmt.md +++ /dev/null @@ -1,336 +0,0 @@ ---- -id: resource_quota_management -title: 资源配额管理 ---- - - - -## 配额配置和规则 -与 Kubernetes 提供的简单命名空间资源配额相比,YuniKorn 可以提供一个更细化的资源配额管理设置。 - -在 Kubernetes 上,一个 pod 在提交时必须符合命名空间的配额。 -如果 pod 不适合命名空间配额, pod 就会被拒绝。 -客户端必须实现重试机制,如果它需要该 pod 被调度,就重新提交该 pod 。 - -与 Kubernetes 中的配额相反, YuniKorn 不在提交时强制执行配额,而只对主动消耗的资源执行配额。 -解释一下区别:当使用 YuniKorn 执行配额时,提交给 Kubernetes 的新 pod 总是被接受。 - Yunikorn 将对 pod 进行排队,而不将排队的 pod 的资源计入已消耗的配额。 -当 YuniKorn 试图调度 pod 时,它会在调度时检查 pod 是否符合为 pod 所分配的队列配置的配额。 -如果这时 pod 不符合配额, pod 就会被跳过,不计入资源消耗。 -这意味着,在一个 pod 的调度尝试成功之前,一个 pod 在 YuniKorn 配额系统中不消耗资源。 - -YuniKorn 中的资源配额与队列及其在队列层次结构中的位置有关。 -队列结构的基础,即 `root` 队列,不允许设置配额,因为它反映了集群的当前规模。 -节点的增加和删除会自动更新 `root` 队列的配额。 - -除了 `root` 队列,配额可以设置,并在层次结构的任何一点上执行。 -每个队列都可以有一个配额设置。配额在整个层次结构中是递归执行的。 -这意味着子队列使用的资源不能超过父队列的**配置的**配额。 -因此,在子队列上设置大于其父队列配额的配额不会有任何影响,并被作为配置错误处理。 - -在层次结构中,还有一些需要考虑的规则。 -如果一个父队列有多个子队列,所有子队列的**使用量之和不能超过父队列的**配置配额。 -然而,从配置的角度来看,这并不意味着所有子队的**配置的**配额之和必须小于父队的配额。 - -![队列定额](./../assets/queue-resource-quotas.png) - -举个例子,`root.parent` 队列的配额是 900。 -它包含三个子队列,其中两个有配额设置。 -`root.parent.child1` 没有设置配额,因此将被限制在 `root.parent` 的配额内。 -另外两个队列 `root.parent.child2` 和 `root.parent.child3` 各设置了 750 的配额。 -在正常运行期间,3 个子队列的总使用量将是 900。 -在每个子队列中运行的应用程序,每个都有超过 1000 的需求。 - -在这种情况下,分配可能是以下任何一种: -* 所有 900 个都被 `child1` 队列使用 -* 平均分布在 3 个队列中(每个队列 300 个)。 -* `child2` 最大使用 750,剩下的 150 由 `child3` 使用。 - -队列之间的确切分布将是波动的,取决于调度策略。 - -## 转换 Kubernetes 资源和配额 - -对pod的资源支持仅限于作为_需求_规范的一部分而指定的资源: - -* _cpu_ 被映射到 _vcore_,其值为 milli cpu。 -* _memory_ 被映射到 _memory_,其值为MB(1 MB = 10^6 B = 1 000 000 B)。 -* 所有其他资源都按照规定进行映射。 - -支持 [Kubernetes文档](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) 中提到的扩展资源。 - -有一个单一容器的 pod 例子: -```yaml -apiVersion: v1 -kind: Pod -spec: - containers: - - name: container-1 - resources: - requests: - cpu: "250m" - memory: "1Gi" - hugepages-1Gi: "1" -``` -上述规范将在 YuniKorn 中为调度设置 pod 资源请求: -* _vcore_ -> 250m -* _memory_ -> 1073741824 -* _hugepages-1Gi_ -> 1 - -两个备注: -多个容器规格将被自动汇总为一个总的 pod 资源请求。所有的内存都是以字节为单位报告的。 - -在为队列使用静态队列定义的情况下,对配额中可指定的资源类型没有限制。 -作为自动队列创建的一部分,命名空间上的配额注释被限制在相当于 _cpu_ 和 _memory_ 的资源。 -参见下面的 [设置](#Namespace-quota),了解命名空间上的配额注释。 - -## Kubernetes 和 YuniKorn 配额互动 -建议关闭而不是配置 Kubernetes 命名空间配额。 -只使用 YuniKorn 队列配额提供了一个更灵活的设置,并允许对工作负载进行排队。 - -在同时开启 YuniKorn 和 Kubernetes 配额的设置中,考虑以下几点: -* 需要维护两个独立的配置。 - 这增加了维护负担,以及配置错误的可能性。 -* 两个配额都会被强制执行。 - -开启这两个配额可能会导致意外的行为。 -主要问题是,Kubernetes 命名空间配额在提交时被强制执行。 -有三种配额配置的组合是可能的。 -当与 YuniKorn 配额结合使用时,这3种组合可能有两种效果。 - -1. 两种配额都是_平等的_:工作负载将不被排队,可以使用全部配置的配额。 - - 最大使用量和排队将被限制在设定的配额内 -2. Kubernetes 配额比 YuniKorn 低:YuniKorn 配额将永远不会达到,工作负载将不会被排队。 - - 最大使用量将被限制在 Kubernetes 的配额内。 -3. Kubernetes 配额比 YuniKorn 高: YuniKorn 将把使用量限制在 YuniKorn 中设置的配额。 - Kubernetes 配额将在提交时强制执行,从而为可以在 YuniKorn 配额之上排队的工作负载设置限制。 - - 最大使用量将被限制在 YuniKorn 的配额内。 - - 工作负载的排队将被限制在 Kubernetes 配额内。 - -:::note -下面的配置例子只是为了演示需要的格式 -来创建一个设置了配额的队列层次结构。 -::: - -## 静态队列定义 - -### 目标 -一个预先配置好的具有最大和保证容量的队列层次结构。 -用户只能向叶子队列提交申请。 -这种方法管理每个队列的资源容量,适用于队列不经常变化的情况。 - -### 配置 -将以下配置应用于 YuniKorn 的 configmap,以: -* 在 `root` 下设置 3 个队列 -* 每个队列都有一个特定的保证和最大容量 -* 任何人都可以向任何队列提交 - -```yaml -partitions: - - name: default - queues: - - name: root - submitacl: '*' - queues: - - name: advertisement - resources: - guaranteed: - memory: 500G - vcore: 50 - max: - memory: 800G - vcore: 80 - - name: search - resources: - guaranteed: - memory: 400G - vcore: 40 - max: - memory: 600G - vcore: 60 - - name: sandbox - resources: - guaranteed: - memory: 100G - vcore: 10 - max: - memory: 100G - vcore: 10 -``` - -### 运行一个工作负载 -为了在特定队列中运行应用程序,你需要在所有 pod 规格中设置以下标签。 -所有具有相同 `applicationID` 标签的 pod 被认为是一个应用程序。 -在下面的例子中,应用程序 `my-test-app` 将在队列 `root.sandbox` 中运行: - -```yaml -labels: - app: my-test-app - applicationId: "my-test-app-01" - queue: root.sandbox -``` - -## 名称空间到队列的映射 - -### 目标 -自动将Kubernetes的 `namespace` 映射到 YuniKorn 的队列。 -用户在 Kubernetes 中创建所需的命名空间。 -YuniKorn k8s shim 和核心调度器会自动传递所需信息,并将命名空间映射到队列中,如果队列不存在,则创建队列。 -资源配额将由 YuniKorn 管理,而不是使用 Kubernetes 命名空间配额。 -这确实需要按照下面的 [设置](#Namespace-quota) 设置命名空间,不需要 Kubernetes 配额的执行和标签。 - -### 配置 -将以下配置应用于 YuniKorn 的配置图: - -```yaml -partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*' - properties: - application.sort.policy: stateaware -``` - -该配置根据 `tag` 规则放置一个应用程序。 -选择的标签是 `namespace` 标签,它由 k8s shim 自动添加到所有被创建的应用程序中。 -`create` 标志被设置为 `true`,如果队列不存在,它将触发与命名空间同名的队列的创建。 - -自动创建的子队列中的应用程序将根据父队列上设置的排序策略进行排序。 -在这种情况下,属性 `application.sort.policy` 在此配置中被设置为 `stateaware` 。 -这是一个适用于批处理作业的简单应用排序策略,你可以找到更多的文件 [这里](sorting_policies.md#StateAwarePolicy)。 - -你可以在安装过程中使用 helm charts 来改变配置,通过覆盖在 -[helm chart template](https://github.com/apache/yunikorn-release/blob/master/helm-charts/yunikorn/values.yaml#L71-L81)。 - -### 命名空间配额 -Kubernetes 中的命名空间包含配额信息。 -如果在命名空间上设置了配额,Kubernetes 将自动执行该配额。 -在 YuniKorn 被用于执行配额的情况下,必须在命名空间上设置配额。 - -为了允许在命名空间上指定配额,应在命名空间对象中设置以下注释: - -```yaml -yunikorn.apache.org/namespace.quota: "{\"cpu\": \"64\", \"memory\": \"100G\", \"nvidia.com/gpu\": \"1\"}" -``` -YuniKorn 将解析这些注释,并设置映射到该命名空间的队列的最大容量。 -指定的值遵循标准的 Kubernetes 格式和单位规范。 -注释值必须是一个符合 json 的字符串。确保双引号被正确转义,以免造成任何问题。 - -上面的例子将把映射到注释命名空间的队列限制在 64 个 CPU、100GB 内存和 1 个 `nvidia.com/gpu`。 - -[已废弃] -以下注释已被废弃,并将在下一个主要版本中被删除。 -它们只支持映射内存和cpu,不支持其他资源类型。 -```yaml -yunikorn.apache.org/namespace.max.cpu: "64" -yunikorn.apache.org/namespace.max.memory: "100Gi" -``` -废弃注释的例子将把队列配额设置为 64 个 CPU 和 100GB 内存。 - -### 运行一个工作负载 - -应用程序,以及作为应用程序一部分的 pod,可以在没有特定标签的情况下提交。 -YuniKorn 将自动添加所需的标签。 -如果需要,配置的放置规则将创建队列,并将应用程序添加到队列中。 - -例如,如果一个应用程序被提交到命名空间 `development` ,那么该应用程序将在 `root.development` 队列中运行。 - -## 命名空间的父队列映射 - -### 目标 -尽管使用 `namespace` 标签的标签放置规则能够将应用程序放置在队列中,但这在所有设置中可能是不够的。 -在某些情况下,例如多租户,命名空间需要被归为一组。 -管理员可以对命名空间进行注释,如果设置了放置规则,可以根据多个注释动态放置应用程序。 -YuniKorn 不能也不会将一个命名空间的所有注解添加到一个应用程序。 - -为了帮助支持这种分组情况,可以在命名空间上标记一个父队列。 - -### 配置 -这个功能的配置由两部分组成: -1. 映射规则 -1. 命名空间注释 - -首先,我们在 YuniKorn 的 configmap 上设置以下配置: - -```yaml -partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - parent: - name: tag - value: namespace.parentqueue - queues: - - name: root - queues: - - name: production - parent: true - - name: development - parent: true -``` - -用于命名空间到队列映射的配置与 [上文](#名称空间到队列的映射) 相同。 -作为放置规则的扩展,添加了一个 `parent` 规则以支持分组。 -父级规则用于生成层次结构中的父级,或上面的队列。 -该规则使用应用程序中的标签 `namespace.parentqueue` 来生成父队列名称。 -`namespace.parentqueue` 标签由 Kubernetes shim 自动添加,但确实需要一个命名空间注释(见下文)。 - -在给出的规则配置示例中,`create` 标志没有在父规则上设置。 -这意味着父队列必须存在于配置中,否则应用提交将失败。 -对于这个例子的配置,这意味着父队的支持值被限制为 `production` 和 `development`。 - -不能使用任何这些映射在父队列上设置配额。 -根据前面提供的命名空间映射,与命名空间相关的配额设置在命名空间队列上,而不是父队。 - -父队列的配额必须总是直接在配置中设置。 -这需要在父规则上将 `create` 标志设置为 `false`。 - -### 命名空间父队列 -与命名空间名称本身相反,并与配额设置相一致,命名空间需要被注解以使用父队列映射。 -命名空间名称在 Kubernetes 中必须是唯一的,这不受此注释的影响。 -相同的注解值可以用于多个命名空间: -```yaml -yunikorn.apache.org/parentqueue: root.production -``` - -上面的例子注释将把父队列映射到现有的 `root.production` 队列。 -注意,如果需要的话,规则将完全限定名称,因此你可以省略注释中的 `root.` 部分。 -如果注释以 `root.` 开头,系统会认为这是一个完全合格的队列名称。 - -为了使图片更完整,这里有一张图片,显示了 YuniKorn 中从 Kubernetes 命名空间到队列的映射。 -它使用了 Kubernetes 中命名空间的注释,以及映射规则的配置示例。 -`finance` 和 `sales`命名空间成为队列,归入父队列 `production` 之下。 -命名空间 `dev` 和 `test` 被放在 `development` 父队列下。 - -![队列配额](./../assets/namespace-mapping.png) - -### 运行一个工作负载 -应用程序,以及作为应用程序一部分的 pod,可以在没有特定标签或更改的情况下提交。 -YuniKorn 将添加标签,安置规则将做其余的事情。 -配置的放置规则将创建队列(如果需要),并将应用程序添加到队列中。 - -由于命名空间 `finance` 被注释为示例值,并且规则已经到位。 -`finance` 命名空间的应用程序将在动态创建的 `root.production.finance` 队列中运行。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/service_config.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/service_config.md deleted file mode 100644 index 362c1af7462..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/service_config.md +++ /dev/null @@ -1,792 +0,0 @@ ---- -id: service_config -title: 服务配置 ---- - - - -YuniKorn的官方版本是通过Helm charts部署到Kubernetes中的。YuniKorn的配置分为两部分:Helm配置和YuniKorn服务配置。 - -## Helm 配置 -Helm配置是用于将YuniKorn部署到Kubernetes的选项。 - -可以在YuniKorn安装期间通过Helm进行以下设置配置,可以使用Helm的命令行方式,例如`--set key=value`,也可以使用外部文件方式:`-f file.yaml`。以下示例将以YAML语法表示。 - -### 容器镜像 -YuniKorn以一组容器镜像的形式提供。可以按照以下方式自定义其位置和拉取策略: - - # 标准调度器的镜像信息 - image: - repository: apache/yunikorn - tag: scheduler-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - - # 插件调度器的镜像信息 - pluginImage: - repository: apache/yunikorn - tag: scheduler-plugin-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - - # Web UI的镜像信息 - web: - image: - repository: apache/yunikorn - tag: web-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - - # 准入控制器的镜像信息 - admissionController: - image: - repository: apache/yunikorn - tag: admission-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - -### Kubernetes 配置 - -#### affinity -设置YuniKorn调度器Pod的亲和性。 - -默认值: `{}` - -示例: - - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: - - primary1 - - primary2 - -#### admissionController.affinity -设置YuniKorn准入控制器Pod的亲和性。 - -默认值: `{}` - -示例: - - admissionController: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: - - primary1 - - primary2 - -#### hostNetwork -控制调度器是否应在主机网络中运行。 - -默认值: `false` - -示例: - - hostNetwork: true - -#### admissionController.hostNetwork -控制准入控制器是否应在主机网络中运行。 - -默认值: `true` - -示例: - - admissionController: - hostNetwork: false - -#### imagePullSecrets -提供提取YuniKorn镜像所需的secret。 - -默认值: `[]` - -示例: - - imagePullSecrets: - - secret1 - - secret2 - -#### nodeSelector -设置用于放置YuniKorn调度器Pod的节点选择算符。 - -默认值: `{}` - -示例: - - nodeSelector: - role.node.kubernetes.io/infra: "true" - -#### admissionController.nodeSelector -设置用于放置YuniKorn准入控制器Pod的节点选择算符。 - -默认值: `{}` - -示例: - - admissionController: - nodeSelector: - role.node.kubernetes.io/infra: "true" - -#### admissionController.replicaCount -设置用于YuniKorn准入控制器的副本数。可以将其设置为大于1以实现高可用性。 - -默认值: `1` - -示例: - - admissionController: - replicaCount: 2 - -#### serviceAccount -为YuniKorn调度器设置备用服务账户。 - -不建议更改此值,因为Helm会为默认用户安装基于角色的访问控制(RBAC)策略,而这对于正确的功能是必需的。 - -默认值: `yunikorn-admin` - -示例: - - serviceAccount: my-account - -#### admissionController.serviceAccount -为YuniKorn准入控制器设置备用服务账户。 - -不建议更改此值,因为Helm会为默认用户安装基于角色的访问控制(RBAC)策略,而这对于正确的功能是必需的。 - -默认值: `yunikorn-admission-controller` - -示例: - - admissionController: - serviceAccount: my-account - -#### service.type -设置用于调度器的服务类型。 - -默认值: `ClusterIP` - -示例: - - service: - type: ClusterIP - -#### admissionController.service.type -设置用于准入控制器的服务类型。 - -默认值: `ClusterIP` - -示例: - - admissionController: - service: - type: ClusterIP - -#### service.port -设置在YuniKorn调度器服务中用于REST API的暴露端口。不建议更改此值。 - -默认值: 9080 - -示例: - - service: - port: 9080 - -#### service.portWeb -设置在YuniKorn调度器服务中用于Web UI的暴露端口。不建议更改此值。 - -默认值: 9889 - -示例: - - service: - portWeb: 9889 - -#### tolerations -设置用于YuniKorn调度器Pod的容忍规则。 - -默认值: `[]` - -示例: - - tolerations: - - key: *infraRoleKey - operator: Equal - value: "true" - effect: NoSchedule - - key: CriticalAddonsOnly - operator: Exists - -#### admissionController.tolerations -设置用于YuniKorn准入控制器Pod的容忍规则。 - -默认值: `[]` - -示例: - - admissionController: - tolerations: - - key: *infraRoleKey - operator: Equal - value: "true" - effect: NoSchedule - - key: CriticalAddonsOnly - operator: Exists - -### 资源利用率 -可以按照以下方式自定义YuniKorn Pod所需的资源: - - # 调度器容器的资源 - resources: - requests: - cpu: 200m - memory: 1Gi - limits: - cpu: 4 - memory: 2Gi - - # Web UI容器的资源 - web: - resources: - requests: - cpu: 100m - memory: 100Mi - limits: - cpu: 100m - memory: 500Mi - - # 准入控制器的资源 - admissionController: - resources: - requests: - cpu: 100m - memory: 500Mi - limits: - cpu: 500m - memory: 500mi - -### 自选功能 - -#### embedAdmissionController -控制是否启用YuniKorn准入控制器。 - -默认值: `true` - -示例: - - embedAdmissionController: false - -#### enableSchedulerPlugin -控制是否以调度器插件模式运行YuniKorn。 - -默认值: `false` - -示例: - - enableSchedulerPlugin: true - -### YuniKorn 默认值 - -#### yunikornDefaults -设置将呈现到 `yunikorn-defaults` ConfigMap的条目。这可以用于在部署时预配置YuniKorn。可以在此处设置 [YuniKorn 配置](#yunikorn-配置) 中声明的任何设置。 - -默认值: `{}` - -示例: - - yunikornDefaults: - service.clusterId: yunikorn-01 - service.policyGroup: group-01 - group-01.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - - -### 弃用设置 -以下设置已被弃用,或在将来的 YuniKorn 版本中被删除。现在应该在 `yunikorn-configs` ConfigMap 或通过 Helm 的 `yunikornDefaults` 部分指定: - -| 弃用设置 | ConfigMap 替代方案 | -| --------------------------------------- | ----------------------------------------------- | -| operatorPlugins | service.operatorPlugins | -| placeHolderImage | service.placeholderImage | -| admissionController: processNamespaces | admissionController.filtering.processNamespaces | -| admissionController: bypassNamespaces | admissionController.filtering.bypassNamespaces | -| admissionController: labelNamespaces | admissionController.filtering.labelNamespaces | -| admissionController: noLabelNamespaces | admissionController.filtering.noLabelNamespaces | -| configuration | queues.yaml | - -以下是一個過時的例子: - - operatorPlugins: general - placeHolderImage: registry.k8s.io/pause:3.7 - admissionController: - processNamespaces: "^spark-,^mpi-" - bypassNamespaces: "^kube-system$" - labelNamespaces: "^spark-" - noLabelNamespaces: "^mpi-legacy-" - configuration: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -以下是替代示例: - - yunikornDefaults: - service.policyGroup: queues - service.operatorPlugins: general - service.placeholderImage: registry.k8s.io/pause:3.7 - admissionController.processNamespaces: "^spark-,^mpi-" - admissionController.bypassNamespaces: "^kube-system$" - admissionController.labelNamespaces: "^spark-" - admissionController.noLabelNamespaces: "^mpi-legacy-" - queues.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -近期,如果同时指定了被弃用的参数和替代的ConfigMap条目,则ConfigMap条目将优先生效。 - - -## YuniKorn 配置 - -YuniKorn的服务配置由两个 Kubernetes ConfigMaps 控制,它们分别是在安装 YuniKorn 的命名空间中:`yunikorn-defaults` 和 `yunikorn-configs`。 - -运行时,YuniKorn会轮询这些ConfigMaps并将它们合并以形成有效配置。如果在两个 ConfigMaps 中都存在某个设置,则 `yunikorn-configs` 中的设置将覆盖 `yunikorn-defaults` 中的设置。 - -`yunikorn-defaults` 的目的是提供一种机制,供 Helm 配置初始的服务配置细节。它不应该被直接修改。 - -`yunikorn-configs` ConfigMap 完全不受 Helm 管理,适用于可能随时间变化的配置,如队列配置。所有对 YuniKorn 配置的更改都应在此处进行,而不是在基础设施供应之外。 - -### 默认 ConfigMap - -如果没有提供任何配置映射,或者某个选项未被指定,YuniKorn将使用此处列出的默认值: - - apiVersion: v1 - kind: ConfigMap - metadata: - name: yunikorn-configs - data: - service.clusterId: "mycluster" - service.policyGroup: "queues" - service.schedulingInterval: "1s" - service.volumeBindTimeout: "10s" - service.eventChannelCapacity: "1048576" - service.dispatchTimeout: "5m" - service.operatorPlugins: "general" - service.disableGangScheduling: "false" - service.enableConfigHotRefresh: "true" - service.placeholderImage: "registry.k8s.io/pause:3.7" - service.instanceTypeNodeLabelKey: "node.kubernetes.io/instance-type" - health.checkInterval: "30s" - log.level: "0" - kubernetes.qps: "1000" - kubernetes.burst: "1000" - admissionController.webHook.amServiceName: "yunikorn-admission-controller-service" - admissionController.webHook.schedulerServiceAddress: "yunikorn-service:9080" - admissionController.filtering.processNamespaces: "" - admissionController.filtering.bypassNamespaces: "^kube-system$" - admissionController.filtering.labelNamespaces: "" - admissionController.filtering.noLabelNamespaces: "" - admissionController.accessControl.bypassAuth: "false" - admissionController.accessControl.trustControllers: "true" - admissionController.accessControl.systemUsers: "^system:serviceaccount:kube-system:" - admissionController.accessControl.externalUsers: "" - admissionController.accessControl.externalGroups: "" - queues.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -### 服务设置 -YuniKorn可理解以下参数: - -#### service.clusterId -为正在配置的集群设置标识符。这将作为REST API调用的一部分返回。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `mycluster` - -示例: - - service.clusterId: "yunikorn-east" - -#### service.policyGroup -定义此调度器使用的策略组。策略组用于选择多个队列配置之一。此设置的值加上`.yaml`的扩展名控制用于检索分区和队列配置的ConfigMap条目。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `queues` - -示例: - - service.policyGroup: group_b - group_b.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -#### service.schedulingInterval -控制YuniKorn执行调度运行的频率。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `1s` - -示例: - - service.schedulingInterval: "5s" - -#### service.volumeBindTimeout -控制卷绑定失败的超时时间。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `10s` - -示例: - - service.volumeBindTimeout: "30s" - -#### service.eventChannelCapacity -控制YuniKorn一次允许有多少个内部调度事件在运行。作為内存不足的保护。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `1048576` - -示例: - - service.eventChannelCapacity: "1000000" - -#### service.dispatchTimeout -控制如果事件通道已满,内部事件将重新尝试调度多长时间。如果超过此超时时间,将发出警告。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `5m` - -示例: - - service.dispatchTimeout: "10m" - -#### service.operatorPlugins -控制在YuniKorn中启用的运算符插件集。目前只实现了 `general`,`spark-k8s-operator` 和 `yunikorn-app` 插件。`general` 插件不应禁用。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `general` - -示例: - - service.operatorPlugins: "general,spark-k8s-operator" - -#### service.disableGangScheduling -允许全局禁用gang调度功能(不建议)。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `false` - -示例: - - service.disableGangScheduling: "true" - -#### service.enableConfigHotRefresh -控制配置是否应该进行热重载。默认情况下,这个设置为 `true`,但是它可以被禁用,以避免 ConfigMaps 的更改被拾起直到调度器重启。 - -更改此设置将在YuniKorn不需要重启的情况下生效。 - -注意:如果禁用了此设置,则可能无法重新启用,除非重新启动YuniKorn。 - -默认值: `true` - -示例: - - service.enableConfigHotRefresh: "false" - -#### service.placeholderImage -设置将用于gang调度占位符的Pod镜像。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `registry.k8s.io/pause:3.7` - -示例: - - service.placeholderImage: "registry.k8s.io/pause:3.6" - -#### service.instanceTypeNodeLabelKey -设置节点标签的键,该键用于标识节点的实例类型。如果设置了此值,则YuniKorn将使用此标签来区分节点的实例类型。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `node.kubernetes.io/instance-type` - -示例: - - service.instanceTypeNodeLabelKey: "node.kubernetes.io/my-instance-type" - -### 健康检查设置 - -#### health.checkInterval -设置YuniKorn自动健康检查的时间间隔。 - -将该值设置为 `0` 或负值将禁用后台健康检查。 - -更改此设置不需要重新启动YuniKorn即可生效。 - -默认值: `30s` - -示例: - - health.checkInterval: "1m" - -### 日志设置 - -#### log.level -设置YuniKorn的日志详细程度。 - -更改此设置不需要重新启动YuniKorn即可生效。可用的值有: - - - `-1`: 调试(Debug) - - `0`: 信息(Info) - - `1`: 警告(Warn) - - `2`: 错误(Error) - - `3`: 不可恢復的錯誤(DPanic) - - `4`: 不可恢復的錯誤(Panic) - - `5`: 致命错误(Fatal) - -默认值: `0` (Info) - -示例: - - log.level: "-1" - -### Kubernetes 设置 - -#### kubernetes.qps -设置 YuniKorn Kubernetes 客户端每秒查询(QPS)的数量。该数字必须>=0。 - -更改此设置需要重新启动 YuniKorn 才能生效。 - -默认值: `1000` - -示例: - - kubernetes.qps: "500" - -#### kubernetes.burst -该设置用于设置 Kubernetes 查询的突发大小,临时允许事件突发到此数字,而不会超过 kubernetes.qps。 - -更改此设置需要重新启动 YuniKorn 才能生效。 - -默认值: `1000` - -示例: - - kubernetes.burst: "500" - -### 准入控制器 webhook 设置 - -#### admissionController.webHook.amServiceName -设置 YuniKorn 准入控制器所在的服务的名称下注册。这是准入控制器注册所必需的本身与 Kubernetes 兼容,通常不应更改。 - -更改此设置需要重新启动 YuniKorn 准入控制器生效。 - -默认值: `yunikorn-admission-controller-service` - -示例: - - admissionController.webHook.amServiceName: "yunikorn-admission-controller-alt-service-name" - -#### admissionController.webHook.schedulerServiceAddress -设置 YuniKorn 调度器服务的地址。这个地址必须是准入控制器可达,并由准入使用验证 ConfigMap 更改时的控制器。准入控制器将联系调度器上的 REST API 以验证任何提议 ConfigMap 更改。通常不应更改此设置。 - -更改此设置需要重新启动 YuniKorn 准入控制器生效。 - -默认值: `yunikorn-service:9080` - -示例: - - admissionController.webHook.schedulerServiceAddress: "alt-yunikorn-service:9080" - -### 准入控制器过滤设置 - -#### admissionController.filtering.processNamespaces -控制哪些命名空间会将 pod 转发给 YuniKorn 进行调度。 - -此设置是以逗号分隔的正则表达式列表。如果这个设置是一个空字符串,在所有命名空间中创建的 pod 将由 YuniKorn 调度。 - -无需重新启动准入控制器即可获取对此设置的更改。 - -默认值: empty - -示例: - - # YuniKorn 仅在 spark-* 和 mpi-* 命名空间中调度 pod - admissionController.filtering.processNamespaces: "^spark-,^mpi-" - -#### admissionController.filtering.bypassNamespaces -该设置控制哪些命名空间的 pod *不会* 被转发到 YuniKorn 进行调度。它作为 `admissionController.filtering.processNamespaces` 的例外列表。 - -此设置是一组逗号分隔的正则表达式。如果该设置为空字符串,则不会从任何命名空间中排除由 YuniKorn 处理的 pod。 - -默认情况下,该设置将排除 kube-system 命名空间中的 pod,因为这些 pod 的调度通常需要成功将节点添加到群集中。这可能会阻止 YuniKorn 本身或其他关键服务的启动。 - -更改此设置将被 admission controller 感知,无需重新启动。 - -默认值: `^kube-system$` - -示例: - - # 不要在 kube-system 或 fluentd-* 命名空间中调度 pod。 - admissionController.filtering.bypassNamespaces: "^kube-system$,^fluentd-" - -#### admissionController.filtering.labelNamespaces -该设置控制哪些命名空间的 pod 将被打上 `applicationId` 标签。默认情况下,所有由 YuniKorn 调度的 pod 都会被打上 `applicationId` 标签。 - -当使用标准部署模型运行 YuniKorn 时,所有 pod 都应打上标签,因为 YuniKorn 无法调度未定义 `applicationId` 的 pod。 - -当使用调度器插件部署模型运行 YuniKorn 时,此设置可用于过滤哪些命名空间应通过 YuniKorn 的队列模型进行调度,哪些命名空间应绕过队列模型并由嵌入式默认调度器进行调度。 - -此设置是一组逗号分隔的正则表达式。如果该设置为空字符串,则将为转发到 YuniKorn 的所有 pod 打上 `applicationId` 标签。 - -更改此设置将被 admission controller 感知,无需重新启动。 - -默认值: empty - -示例: - - # 将 applicationId 标签添加到 spark-* 命名空间中的 pod。 - admissionController.filtering.labelNamespaces: "^spark-" - -#### admissionController.filtering.noLabelNamespaces -该设置控制哪些命名空间的 pod *不会* 打上` applicationId` 标签。它作为 `admissionController.filtering.labelNamespaces` 的例外列表。 - -当使用标准部署模型运行 YuniKorn 时,所有 pod 都应打上标签,因为 YuniKorn 无法调度未定义 `applicationId` 的 pod。 - -当使用调度器插件部署模型运行 YuniKorn 时,此设置可用于过滤哪些命名空间应通过 YuniKorn 的队列模型进行调度,哪些命名空间应绕过队列模型并由嵌入式默认调度器进行调度。 - -此设置是一组逗号分隔的正则表达式。如果该设置为空字符串,则不会应用到 `admissionController.filtering.labelNamespaces` 的任何例外。 - -更改此设置将被 admission controller 感知,无需重新启动。 - -默认值: empty - -示例: - - # 在命名空间为 noqueue 时跳过队列。 - admissionController.filtering.labelNamespaces: "^noqueue$" - -### 准入控制器访问控制列表(ACL)设置 - -#### admissionController.accessControl.bypassAuth -允许外部用户创建带有用户信息的 pod。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: `false` - -示例: - - admissionController.accessControl.bypassAuth: "true" - -#### admissionController.accessControl.trustControllers -允许控制器用户创建带有用户信息的 pod。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: `true` - -示例: - - admissionController.accessControl.trustControllers: "false" - -#### admissionController.accessControl.systemUsers -逗号分隔的正则表达式列表,用于匹配允许的控制器服务账户。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: `^system:serviceaccount:kube-system:` - -示例: - - # 允许所有的 kube-system 账户以及 kube-controller-manager - admissionController.accessControl.systemUsers: "^system:serviceaccount:kube-system,^system:kube-controller-manager$" - -#### admissionController.accessControl.externalUsers -逗号分隔的正则表达式列表,用于匹配允许的外部用户。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: empty - -示例: - - # 允许 'alice'、'bob' 和 'admin-*' - admissionController.accessControl.externalUsers: "^alice$,^bob$,^admin-" - -#### admissionController.accessControl.externalGroups -逗号分隔的正则表达式列表,用于匹配允许的外部用户组。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: empty - -示例: - - # 允许 'sales'、'marketing' 和 'admin-*' - admissionController.accessControl.externalGroups: "^sales$,^marketing$,^admin-" - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/sorting_policies.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/sorting_policies.md deleted file mode 100644 index 49d64e9002d..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/sorting_policies.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -id: sorting_policies -title: 排序策略 ---- - - - -调度器使用策略可以在不更改代码的情况下改变调度行为。 -可以为以下项目设置策略: -* [应用程序](#应用程序排序) -* [节点](#节点排序) -* [请求](#请求排序) - -## 应用程序排序 -通过配置为每个队列设置应用程序排序策略。排序策略设置仅对*叶子*队列有效。每个*叶子*队列可以使用不同的策略。 - -排序策略仅指定应用程序在队列内排序的顺序。 -该顺序对于指定在分配资源时首先考虑哪个应用程序非常重要。 -排序策略*不会*影响在队列中同时调度或激活的应用程序数量。 -所有具有待处理资源请求的应用程序都可以并且将在队列中调度,除非明确地被过滤掉。 -即使使用先进先出策略(FIFO)对应用程序进行排序,多个应用程序也将在队列中并行运行。 - -*父*队列始终使用公平策略对子队列进行排序。 - -考虑子队列的相对优先级(在*父*队列排序的情况下)和应用程序的相对优先级(在*叶子*队列排序的情况下)。 -要在调度时忽略应用程序和队列优先级,请将队列属性`application.sort.priority`设置为`disabled`。 - -以下配置条目将应用程序排序策略设置为FIFO,适用于队列`root.sandbox`: - -```yaml -partitions: - - name: default - queues: - - name: root - queues: - - name: sandbox - properties: - application.sort.policy: fifo -``` - -仅考虑具有未处理请求的应用程序进行调度。 -在排序应用程序*时*应用筛选器以移除所有没有未处理请求的应用程序。 - -### FifoSortPolicy -简短描述:先进先出,基于应用程序创建时间。 - -配置值:`fifo`(默认) - -在排序之前,需要过滤应用程序,并且必须有挂起(pending)的资源请求。 - -经过筛选后,应用程序将根据创建时间戳进行排序,不会使用其他过滤。 -由于系统仅在锁定状态下添加应用程序,因此不可能有两个具有完全相同时间戳的应用程序。 - -结果,最早的请求资源的应用程序获得资源。 -较晚请求的应用程序将在满足之前应用程序当前所有请求之后获得资源。 - -### FairSortPolicy -简短描述:基于资源利用率公平性排序。 - -配置值: `fair` - -在排序之前,需要过滤应用程序,并且必须有挂起(pending)的资源请求。 - -经过筛选后,剩下的应用程序将根据使用情况进行排序。 -应用程序的使用情况是指应用程序所有已确认和未确认的分配。 -计算使用情况时,将考虑应用程序中定义的所有资源。 - -达到的效果是资源相对平均分配给所有请求资源的应用程序 - -### StateAwarePolicy -简短描述:限制同一时间只有一个为 Starting 或 Accepted 状态的应用程序。 - -配置值: `stateaware` - -此排序策略需要了解应用程序状态。 -应用程序状态在[应用程序状态](design/scheduler_object_states.md#application-state)文档中进行了描述。 - -在对所有排队的应用程序进行排序之前,将应用以下过滤器: -第一个过滤器基于应用程序状态。 -以下应用程序通过过滤器并生成第一个中间列表: -* 处于 *running* 状态的所有应用程序 -* *一个*(1)处于 *starting* 状态的应用程序 -* 如果*没有*处于 *starting* 状态的应用程序,则添加 *一个*(1)处于 *accepted* 状态的应用程序 - -第二个过滤器将第一个过滤器的结果作为输入。 -再次过滤初步列表:删除所有*没有*挂起(pending)请求的应用程序。 - -根据状态和挂起(pending)请求进行过滤后,剩余的应用程序将进行排序。 -因此,最终列表将使用剩余的应用程序两次过滤并按创建时间排序。 - -回顾下 *Starting* 和 *Accepted* 状态的交互: -只有在没有处于 *Starting* 状态的应用程序时,才会添加处于 *Accepted* 状态的应用程序。 -处于 *Starting* 状态的应用程序不必有挂起(pending)请求。 -任何处于 *Starting* 状态的应用程序都将防止 *Accepted* 应用程序被添加到已过滤的列表中。 - -有关详细信息,请参阅设计文档中的 [示例](design/state_aware_scheduling.md#example-run) 运行。 - -达到的效果是,已经在运行的应用程序讲优先得到资源。 -在所有已运行的应用程序后,逐一调度新的应用程序。 - - -## 节点排序 -节点排序策略通过配置文件为每个分区设置,不同的分区可以使用不同的策略。 -以下配置项将分区`default`的节点排序策略设置为`fair`: -```yaml -partitions: - - name: default - nodesortpolicy: - type: fair -``` - -### FairnessPolicy -简要描述:按可用资源排序,按降序排列 - -配置值:`fair` (默认值) - -行为: -按可用资源的数量对节点列表进行排序,使具有最高可用资源量的节点排在列表的第一位。 -计算使用情况时,将考虑节点上定义的所有资源。 -对于节点的相同类型资源进行比较。 - -这将导致考虑可用性最低的节点首先进行新分配的分配,从而在所有可用节点上分散分配。 -这将导致每个可用节点的整体利用率降低,除非整个环境的利用率非常高。 -将所有节点的负载保持在相似水平有助于。 -在自动缩放添加新节点的环境中,这可能会触发意外的自动缩放请求。 - -### BinPackingPolicy -简要描述:按可用资源排序,按升序排列 - -配置值:`binpacking` - -行为: -按可用资源的数量对节点列表进行排序,使具有最低可用资源量的节点排在列表的第一位。 -计算使用情况时,将考虑节点上定义的所有资源。 -对于节点的相同类型资源进行比较。 - -这将导致考虑可用性最高的节点首先进行新分配的分配,从而使少量节点的利用率更高,更适合云部署。 - -## 资源加权 -节点排序策略可能使用节点利用率来确定顺序。 -因为节点可以具有多个唯一的资源类型,所以节点的利用率是由其各个资源类型的加权平均值确定的。 -资源加权可以通过使用`nodesortpolicy`的`resourceweights`部分进行自定义。 -如果`resourceweights`不存在或为空,则默认配置将`vcore`和`memory`的权重设置为相等的`1.0`。 -所有其他资源类型都将被忽略。 -只有明确提到的资源类型才会具有权重。 - -YuniKorn在内部跟踪CPU资源作为`vcore`资源类型。 -这将映射到Kubernetes资源类型`cpu`。 -除`vcore`和memory之外,所有其他资源类型在YuniKorn和Kubernetes之间具有一致的命名。 - -例如,在默认配置中,如果节点的CPU和内存分别分配了`90%`和`50%`,则该节点将被视为已使用`70%`。 - -以下配置条目为分区default设置了`vcore`权重为`4.0`和`memory`权重为`1.0`。 -这将使CPU使用的权重比内存使用高四倍: -```yaml -partitions: - - name: default - nodesortpolicy: - type: fair - resourceweights: - vcore: 4.0 - memory: 1.0 -``` - -使用此配置,在此示例中,如果节点的CPU和内存分别分配了`90%`和`50%`,则该节点将被视为已使用`82%`。 - -请注意,权重是相对于彼此的,因此指定`{4.0,1.0}`的权重等效于`{1.0,0.25}`。不允许负权重。 - -## 请求排序 -当前仅有一种策略可用于在应用程序内对请求进行排序。 -此策略不可配置。 -仅可以基于请求的优先级对请求进行排序。 -如果应用程序中有多个具有相同优先级的请求,则请求的顺序未确定。 -这意味着具有相同优先级的请求的顺序可能会在运行之间改变。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/troubleshooting.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/troubleshooting.md deleted file mode 100644 index 4b47d6b0ab4..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/troubleshooting.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -id: troubleshooting -title: 故障排除 ---- - - - -## 调度日志(Scheduler logs) - -### 检索调度日志 - -调度器会将日志写入stdout/stderr,docker容器就会将这些日志重新导向到节点的本地位置,你可以从[这里](https://docs.docker.com/config/containers/logging/configure/)读到更多的文档,这些日志可以通过[kuberctl logs](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs)检索。如: - -```shell script -//获取调度的pod -kubectl get pod -l component=yunikorn-scheduler -n yunikorn -NAME READY STATUS RESTARTS AGE -yunikorn-scheduler-766d7d6cdd-44b82 2/2 Running 0 33h - -//检索日志 -kubectl logs yunikorn-scheduler-766d7d6cdd-44b82 yunikorn-scheduler-k8s -n yunikorn -``` - -在大多数的情况下,这个命令没有办法获取所有的日志,因为调度程序的日志数量庞大,您需要设置[集群级别的日志收集](https://kubernetes.io/docs/concepts/cluster-administration/logging/#cluster-level-logging-architectures)。推荐的设置方式是利用[fluentd](https://www.fluentd.org/)在外部储存(例如s3)上持久的收集日志。 - -### 设定日志级别 - -### -:::note -我们建议通过REST API来调整日志级别,如此以来我们不需要每次修改级别时重新启动调动程序的pod。但是透过编辑部署配置来设定日志级别时,需要重新启用调度程序的pod,因此强烈不建议这么做。 -::: - -停止调度器: -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -``` - -使用vim编辑部署配置: -```shell script -kubectl edit deployment yunikorn-scheduler -n yunikorn -``` - -在容器模板的`env`字段中加入`LOG_LEVEL`。例如将`LOG_LEVEL`设置为0会将日志纪录的级别设置为`INFO`。 - -```yaml -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: -… -spec: -template: -… -spec: -containers: -- env: -- name: LOG_LEVEL -value: '0' -``` - -启用调度器: -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -可使用的日志级别: - -| 值 | 日志级别 | -|:-----: |:-------------: | -| -1 | DEBUG | -| 0 | INFO | -| 1 | WARN | -| 2 | ERROR | -| 3 | DPanic | -| 4 | Panic | -| 5 | Fatal | - -## Pods卡在`Pending`状态 - -如果Pod卡在Pending状态,则意味着调度程序找不到分配Pod的节点。造成这种情况有以下几种可能: - -### 1.没有节点满足pod的放置要求 - -可以在Pod中配置一些放置限制,例如[节点选择器(node-selector)](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)、[亲合/反亲合性(affinity/anti-affinity)](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)、对节点的[污点(taints)](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)没有一定的容忍度等。若要修正此类问题,你可以通过以下方法观察pod: - -```shell script -kubectl describe pod -n <命名空间> -``` - -pod事件中包含预测失败,而这解释了为什么节点不符合分配条件 - -### 2.队列的可用资源不足 - -如果队列的可用资源不足,Pod将等待队列资源。检查队列是否还有空间可以给Pending pod的方法有以下几种: - -1 ) 从Yunikorn UI检查队列使用情况 - -如果你不知道如何访问UI,可以参考[这里](../get_started/get_started.md#访问-web-ui)的文档。在`Queues`页面中,寻找Pod对应到的队列。你将能够看到队列中剩馀的可用资源。 - -2 ) 检查pod事件 - -运行`kubectl describe pod`以获取pod事件。如果你看到类似以下的事件:`Application does not fit into <队列路径> queue`。则代表pod无法分配,因为队列的资源用完了。 - -当队列中的其他Pod完成工作或被删除时,代表目前Pending的pod能得到分配,如果Pod依旧在有足够的剩馀资源下,保持pending状态,则可能是因为他正在等待集群扩展。 - -## 获取完整的状态 - -Yunikorn状态储存中,包含了对每个进程中每个对象的状态。透过端点来检索,我们可以有很多有用的信息,举一个故障排除的例子:分区列表、应用程序列表(包括正在运行的、已完成的以及历史应用程序的详细信息)、节点数量、节点利用率、通用集群信息、集群利用率的详细信息、容器历史纪录和队列信息。 - -状态是Yunikorn提供的用于故障排除的宝贵资源。 - -有几种方法可以获得完整的状态: -### 1.调度器URL - -步骤: -*在浏览器中打开Yunikorn UI,且在URL中编辑: -*将`/#/dashboard`取代为`/ws/v1/fullstatedump`,(例如,`http://localhost:9889/ws/v1/fullstatedump`) -*按下回车键。 - -透过这个简单的方法来观看即时且完整的状态。 - -### 2.调度器的REST API - -使用以下的调度器REST API,能够让我们看到Yunikorn的完整状态。 - -`curl -X 'GET'http://localhost:9889/ws/v1/fullstatedump-H 'accept: application/json'` - -有关储存状态的更多信息,可以参阅[检索完整状态](api/scheduler.md#retrieve-full-state-dump)的文档。 - -## 重启调度器 -:::note -最好的故障排除方法是─把「重启调度器」当作完全没有其他方法之下的最后一步,他不应该在搜集所有日志和状态之前使用。 -::: - -Yunikorn可以在重启之后恢复其状态。Yunikorn调度器的pod作为deployment部署。我们可以透过`scale`来增加和减少副本数量来重启Yunikorn调度器,方法如下: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -## 成组调度 -### 1.没有占位符被创建,且app处于pending状态 -*原因*:这通常是因为应用程序被调度气拒绝,因此没有一个pod被调度。 - -导致拒绝的常见原因有: - -1)任务群组(taskGroups)定义无效。调度程序在应用程序被提交时会进行健全性检查,以确保正确定义所有任务群组,如果这些信息的格式不正确,调度程序将拒绝该应用程序 - -2)任务群组中定义的总最小资源量大于队列的最大资源量,因此调度程序拒绝该应用程序,因为队列的资源量无法满足它。可以通过检查pod事件中的相关消息,或调度器日志来找到更多详细的错误信息。 - -*解决方案*:更正任务群组的定义并重新提交应用程序。 - -### 2.有些占位符没有被分配 -*原因*:占位符也会消耗资源,如果不能全部分配,通常是队列或者集群没有足够的资源分配给它们。在这种情况下,占位符将在一定时间后被清理,该时间由调度策略参数─`placeholderTimeoutInSeconds`所定义。 - -*解决方案*:如果占位符超时了,目前的app将会转为failed状态,无法再被调度。如果您愿意等待更长的时间,可以增加占位符超时的值。将来可能会添加倒退策略以提供重试,而不是使应用程序失败。 - -### 3.有些占位符没有被交换 -*原因*:这通常代表应用程序的pod少于任务群组中定义的最小成员数(`minMembers`) - -*解决方案*:检查任务群组字段中的`minMember`并确保其设置正确。`minMember`可以小于实际的pod数,设置大于实际pod数是无效的。 - -### 4.应用程序终止时不会清除占位符 -*原因*:所有占位符都会设置[ownerReference](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents)到应用程序的第一个真实的pod,或控制器参考。如果无法清理占位符,则意味着垃圾回收(garbage collector)的机制不正常。 - -*解决方案*:检查占位符的`ownerReference`和Kubernetes中的垃圾收集器。 - -## 仍然遇到问题? -没问题!Apache Yunikorn社区将很乐意提供帮助。您可以通过以下选项联系社区: - -1. 将您的问题发布到dev@yunikorn.apache.org。 -2. 加入[YuniKorn slack](https://join.slack.com/t/yunikornworkspace/shared_invite/enQtNzAzMjY0OTI4MjYzLTBmMDdkYTAwNDMwNTE3NWVjZWE1OTczMWE4NDI2Yzg3MmEyZjUyYTZlMDE5M2U4ZjZhNmYyNGFmYjY4ZGYyMGE)并将您的问题发布到`#yunikorn-user`频道。 -3. 加入[社区会议](http://yunikorn.apache.org/community/get_involved#community-meetings)并直接与社区成员交谈。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/usergroup_resolution.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/usergroup_resolution.md deleted file mode 100644 index 7702498cd21..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/usergroup_resolution.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -id: usergroup_resolution -title: 解析用户和群组 ---- - - - -## 用户解析 (User resolution) - -用户信息是调度周期的重要概念,他是決定「是否将作业提交到队列」的关键指标之一。Yunikorn调度器依赖k8s Shim来提供用户信息,但在Kubernetes的世界中,没有任何对象可以识别实际用户,这是基于设计使然,可以从这个[页面](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#users-in-kubernetes)中得到更多资讯。 - -在Yunikorn中有两种处理用户和群组的方法。第一种是传统的方式,使用标签`yunikorn.apache.org/usernname`。如果此标签设置在pod上,则该值会自动提取到shim中并被使用。群组解析也在shim中完成,但预设是不启用的。这种方法的问题有两个方面:首先,用户限制可以很容易地被绕过,因为提交者可以自由地将标签设置为任何值,因此这只能在受信任的环境中使用。其次,在shim中识别组别太慢了─将用户分配到多个群组​是不可行的,因为根据身份验证机制(如X509,tokens,LDP,etc)可能很难查找用户属于哪一个群组。 - -由于这些限制很大,为了向后兼容才保留了此方法,且将来可能会被删除。 - -一种更可靠和健全的机制是使用`yunikorn.apache.org/user.info`,其中用户信息中的「允许的用户或群组列表」可以由从外部设置,或者准入控制(admission controller)可以自动将其附加到每个工作负载(workflow)。 - -## 传统的用户处理 - -### 使用`yunikorn.apache.org/username`标签 - -由于kubernetes没有预定义的字段和资源能用于用户信息,且个别集群使用的用户识别工具可能有所不同,于是我们定义了标准的方法来识别用户。Yunikorn需要添加一个kubernetes[标签](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)。这里提供了[推荐的使用方法](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/),预设的标签定义如下: - -|标签|值| -|----------------------------------------------- |--------------------- | -| yunikorn.apache.org/username |用户名。可以重复该条目,但只会使用第一个值。默认的用户是`nobody` | - -举例: -```yaml -metadata: - labels: - yunikorn.apache.org/username:"john" -``` -:::tip -为了让该字段(field)成为唯一识别用户的指标,建议集群管理员使用用户识别工具,将这个标签设为不可变的字段。集群管理员或用户可以自由的使用任何方法或工具来增加这个字段和值。其中包含在提交时手动添加。 -::: - -:::note 假设 -假设: -Yunikorn假设一个应用程序的所有pod都属于同一个用户。我们建议将用户标签添加到应用程序的每个pod。这是为了确保没有任何意外。 -::: - -在[K8s的部署](https://github.com/apache/yunikorn-release/blob/master/helm-charts/yunikorn/templates/deployment.yaml)时,可以通过覆盖`USER_LABEL_KEY`来改变标签`yunikorn.apache.org/username`的默认值,这在已经添加用户标签,或出于某些安全因素下必须修改标签的情况下特别有用。 - -```yaml - env: - - name: USER_LABEL_KEY - value:"custom_user_label" -``` - -### 群组解析 (Group resolution) - -这里包含群组成员解析的定义,此外该功能是可以选择加入或移除的。群组不必是用户或群组对象所提供的一部分。当对象被加到缓存中时,群组将自动根据配置来解析。可以为每个分区(partition)设置连接到缓存的解析器(resolver)。 - -预设的群组解析器是"no resolver"。此解析器仅回传用户明和与用户同名的主要群组。 - -其他解析器: -* 操作系统解析器 -* 测试解析器 - -## 推荐的处理用户的新方式 - -从Yunikorn 1.2开始,可以使用更复杂的用户/群组解析方式。 - -在这种模式下,Yunikorn不再依赖标签`yunikorn.apache.org/username`,而是将`yunikorn.apache.org/user.info`附加到工作负载。通过简单的JSON值,定义用户名和群组: - -```yaml -metadata: - annotations: - yunikorn.apache.org/user.info:" - { - username: \"yunikorn\", - groups: [ - \"developers\", - \"devops\" - ] - }" -``` - -然而,为了加强安全性,在准入控制器中强制执行了以下操作: -* 不是集群中的每个用户都可以附加此注解(annotation),只有在配置允许时才可以使用。 -* 如果缺少注解,则准入控制器将自动添加。 -* 若尝试修改此注解将会被拒绝。 - -我们不只在pods上这样做,而是在Deployments,ReplicaSet,DeamonSet,StatefulSet,Jobs和CronJobs上都这样做。 - -此外,群组解析器不再需要放在k8s-shim中。 - -### 配置准入控制器 - -准入控制可以在`yunikorn-configs`的configmap中被配置。所有条目都以前缀`admissionController.accessControl.`开头。 - -|变量|默认值|描述| -|--|--|--| -|`bypassAuth`|false|允许任何外部用户使用用户信息集创建pod| -|`trustControllers`|true|允许Kubernetes控制器的用户创建带有用户信息集的pod| -|`systemUsers`|"^system:serviceaccount:kube-system:"|允许控制器符物帐号列表使用正则表达式| -|`externalUsers`|""|在「允许的外部用户列表」上使用正则表达式| -|`externalGroups`|""|在「允许的外部群组列表」上使用正则表达式| - -如果`bypassAuth`设置为`true`,但注解不存在且设定了已遗弃的用户标签,则准入控制器将不会把注解加到pod中。如果未设置注解也未设置用户标签,则新的注解将会被加入。 -在`bypassAuth`为`false`(默认值)的情况下,准入控制器将始终添加新的注解,而不管是否存在已弃用的标签。 - -在某些情况下,必须将用户和群组在提交时提供给Yunikorn,因为用户和群组管理由外部系统提供,查找机制并不简单。因此,在这些情况下,可以将`externalUsers`和`externalGroups`配置为正则表达式。其中,匹配的用户或群组就可以将`yunikorn.apache.org/user.info`设置为任意值。但这会影响Yunikorn内部的调度,因此必须仔细设置这些属性。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_flink.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_flink.md deleted file mode 100644 index 40eb05b1978..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_flink.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: run_flink -title: 运行Flink作业 -description: 如何与YuniKorn一起运行Flink作业 -image: https://svn.apache.org/repos/asf/flink/site/img/logo/png/100/flink_squirrel_100_color.png -keywords: - - spark ---- - - - -使用 YuniKorn 在 Kubernetes 上运行 [Apache Flink](https://flink.apache.org/) 非常容易。 -根据在 Kubernetes 上运行 Flink 的模式不同,配置会略有不同。 - -## Standalone(独立)模式 - -请关注 [Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/kubernetes.html) 以获取 standalone 部署模式的细节和示例。 -在这种模式下,我们可以直接在 Deployment/Job spec 中添加需要的标签(applicationId 和 queue)来使用 YuniKorn 调度器运行 flink 应用程序,以及 [使用 YuniKorn 调度器运行 workloads](#run-workloads-with-yunikorn-scheduler) . - -## Native(原生)模式 - -请关注 [原生 Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/native_kubernetes.html) 以获取原生部署模式的细节和示例。 -只有 Flink 1.11 或更高版本才支持在 native 模式下使用 YuniKorn 调度程序运行 Flink 应用程序,我们可以利用两个 Flink 配置 `kubernetes.jobmanager.labels` 和 `kubernetes.taskmanager.labels` 来设置所需的标签。 -例子: - -* 启动一个 Flink session -``` -./bin/kubernetes-session.sh \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dresourcemanager.taskmanager-timeout=3600000 \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox -``` - -* 启动一个 Flink application -``` -./bin/flink run-application -p 8 -t kubernetes-application \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dkubernetes.container.image= \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - local:///opt/flink/usrlib/my-flink-job.jar -``` \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_mpi.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_mpi.md deleted file mode 100644 index 374c5ca1e68..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_mpi.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: run_mpi -title: 运行MPI作业 -description: 在Yunikorn中运行MPI作业 -keywords: - - mpi ---- - - - -本指南介绍将介绍如何设置[MPI Operator](https://github.com/kubeflow/mpi-operator),以及如何使用YuniKorn调度程序运行MPIJob。 - -## 安装MPI操作器 -您可以使用以下命令安装MPI操作器。如果您在安装时遇到问题,请参阅[此文档](https://github.com/kubeflow/mpi-operator)了解详细信息。 -``` -kubectl create -f https://raw.githubusercontent.com/kubeflow/mpi-operator/master/deploy/v2beta1/mpi-operator.yaml -``` - -## 运行MPI作业 -此示例显示如何运行MPI应用程序。 - -此程序将印出一些关于workers的基础信息,然后计算圆周率的近似值。 - -这是一个计算圆周率的[YAML示例](https://github.com/apache/yunikorn-k8shim/blob/master/deployments/examples/mpioperator/Pi/pi.yaml): - -```yaml -apiVersion: kubeflow.org/v2beta1 -kind: MPIJob -metadata: - name: pi -spec: - slotsPerWorker: 1 - runPolicy: - cleanPodPolicy: Running - ttlSecondsAfterFinished: 60 - sshAuthMountPath: /home/mpiuser/.ssh - mpiReplicaSpecs: - Launcher: - replicas: 1 - template: - labels: - applicationId: "mpi_job_pi" - queue: root.mpi - spec: - schedulerName: yunikorn - containers: - - image: mpioperator/mpi-pi - name: mpi-launcher - securityContext: - runAsUser: 1000 - command: - - mpirun - args: - - -n - - "2" - - /home/mpiuser/pi - resources: - limits: - cpu: 1 - memory: 1Gi - Worker: - replicas: 2 - template: - labels: - applicationId: "mpi_job_pi" - queue: root.mpi - spec: - schedulerName: yunikorn - containers: - - image: mpioperator/mpi-pi - name: mpi-worker - securityContext: - runAsUser: 1000 - command: - - /usr/sbin/sshd - args: - - -De - - -f - - /home/mpiuser/.sshd_config - resources: - limits: - cpu: 1 - memory: 1Gi -``` -创建一个MPIJob。 -``` -kubectl create -f deployments/examples/mpioperator/Pi/pi.yaml -``` - -我们在圆周率示例中添加了Yunikorn标签,以演示如何使用yunikorn调度程序。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_spark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_spark.md deleted file mode 100644 index 45791a18427..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/run_spark.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: run_spark -title: 运行Spark作业 -description: 如何使用YuniKorn运行Spark作业 -keywords: - - spark ---- - - - -:::note 注意 -本文档假设您已安装YuniKorn及其准入控制器。请参阅 [开始](../../get_started/get_started.md) 查看如何操作。 -::: - -## 为Spark准备docker镜像 - -要在Kubernetes上运行Spark,您需要Spark的docker镜像。您可以 -1)使用Spark团队提供的docker镜像 -2)从头开始构建一个镜像。如果你想建立自己的Spark的docker镜像,您可以找到 [完整说明](https://spark.apache.org/docs/latest/building-spark.html) -在 Spark 文档中。简化步骤: -* 下载一个支持Kubernetes的Spark版本,URL: https://github.com/apache/spark -* 构建支持Kubernetes的Spark版本: -```shell script -./buid/mvn -Pkubernetes -DskipTests clean package -``` -建议使用[dockerhub](https://hub.docker.com/r/apache/spark/tags)中不同spark版本的官方镜像 - -## 为Spark作业创建一个命名空间 - -创建一个命名空间: - -```shell script -cat < - -本章节概述了如何设置 [training-operator](https://github.com/kubeflow/training-operator) 以及如何使用 YuniKorn 调度器运行 Tensorflow 作业。 -training-operator 是由 Kubeflow 维护的一体化集成的训练 operator。它不仅支持 TensorFlow,还支持 PyTorch、XGboots 等。 - -## 安装 training-operator -您可以使用以下命令在 kubeflow 命名空间中默认安装 training operator。如果安装有问题, -请参阅 [此文档](https://github.com/kubeflow/training-operator#installation) 来查找相关的详细信息。 -``` -kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone?ref=v1.3.0" -``` - -## 准备 docker 镜像 -在开始于 Kubernetes 上运行 TensorFlow 作业之前,您需要构建 docker 镜像。 -1. 从 [deployment/examples/tfjob](https://github.com/apache/yunikorn-k8shim/tree/master/deployments/examples/tfjob) 上下载文件 -2. 使用以下命令构建这个 docker 镜像 - -``` -docker build -f Dockerfile -t kubeflow/tf-dist-mnist-test:1.0 . -``` - -## 运行一个 TensorFlow 作业 -以下是一个使用 MNIST [样例](https://github.com/apache/yunikorn-k8shim/blob/master/deployments/examples/tfjob/tf-job-mnist.yaml) 的 TFJob yaml. - -```yaml -apiVersion: kubeflow.org/v1 -kind: TFJob -metadata: - name: dist-mnist-for-e2e-test - namespace: kubeflow -spec: - tfReplicaSpecs: - PS: - replicas: 2 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 - Worker: - replicas: 4 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 -``` -创建 TFJob -``` -kubectl create -f deployments/examples/tfjob/tf-job-mnist.yaml -``` - -您可以从 YuniKorn UI 中查看作业信息。 如果您不知道如何访问 YuniKorn UI, -请阅读此 [文档](../../get_started/get_started.md#访问-web-ui)。 - -![tf-job-on-ui](../../assets/tf-job-on-ui.png) - -## 使用GPU Time-slicing -### 前提 -要使用 Time-slicing GPU,您需要先设定丛集以让GPU和Time-slicing GPU能被使用。 -- 节点上必须连接GPU -- Kubernetes版本为1.24 -- 丛集中需要安装 GPU drivers -- 透过 [GPU Operator](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/getting-started.html) 自动化的建置与管理节点中的 NVIDIA 软体组件 -- 在Kubernetes中设定 [Time-Slicing GPUs in Kubernetes](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/gpu-sharing.html) - - -在安装完 GPU Operator 及 Time-slicing GPU 以后,确认pods的状态以确保所有的containers正在运行或完成: -```shell script -kubectl get pod -n gpu-operator -``` -```shell script -NAME READY STATUS RESTARTS AGE -gpu-feature-discovery-fd5x4 2/2 Running 0 5d2h -gpu-operator-569d9c8cb-kbn7s 1/1 Running 14 (39h ago) 5d2h -gpu-operator-node-feature-discovery-master-84c7c7c6cf-f4sxz 1/1 Running 0 5d2h -gpu-operator-node-feature-discovery-worker-p5plv 1/1 Running 8 (39h ago) 5d2h -nvidia-container-toolkit-daemonset-zq766 1/1 Running 0 5d2h -nvidia-cuda-validator-5tldf 0/1 Completed 0 5d2h -nvidia-dcgm-exporter-95vm8 1/1 Running 0 5d2h -nvidia-device-plugin-daemonset-7nzvf 2/2 Running 0 5d2h -nvidia-device-plugin-validator-gj7nn 0/1 Completed 0 5d2h -nvidia-operator-validator-nz84d 1/1 Running 0 5d2h -``` -确认时间片设定是否被成功的使用: -```shell script -kubectl describe node -``` - -```shell script -Capacity: - nvidia.com/gpu: 16 -... -Allocatable: - nvidia.com/gpu: 16 -... -``` -### 使用GPU测试TensorFlow job -在这个段落中会在 Time-slicing GPU 的支援下,测试及验证TFJob的运行 - -1. 新建一个workload的测试档案tf-gpu.yaml: - ```shell script - vim tf-gpu.yaml - ``` - ```yaml - apiVersion: "kubeflow.org/v1" - kind: "TFJob" - metadata: - name: "tf-smoke-gpu" - namespace: kubeflow - spec: - tfReplicaSpecs: - PS: - replicas: 1 - template: - metadata: - creationTimestamp: - labels: - applicationId: "tf_job_20200521_001" - spec: - schedulerName: yunikorn - containers: - - args: - - python - - tf_cnn_benchmarks.py - - --batch_size=32 - - --model=resnet50 - - --variable_update=parameter_server - - --flush_stdout=true - - --num_gpus=1 - - --local_parameter_device=cpu - - --device=cpu - - --data_format=NHWC - image: docker.io/kubeflow/tf-benchmarks-cpu:v20171202-bdab599-dirty-284af3 - name: tensorflow - ports: - - containerPort: 2222 - name: tfjob-port - workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks - restartPolicy: OnFailure - Worker: - replicas: 1 - template: - metadata: - creationTimestamp: null - labels: - applicationId: "tf_job_20200521_001" - spec: - schedulerName: yunikorn - containers: - - args: - - python - - tf_cnn_benchmarks.py - - --batch_size=32 - - --model=resnet50 - - --variable_update=parameter_server - - --flush_stdout=true - - --num_gpus=1 - - --local_parameter_device=cpu - - --device=gpu - - --data_format=NHWC - image: docker.io/kubeflow/tf-benchmarks-gpu:v20171202-bdab599-dirty-284af3 - name: tensorflow - ports: - - containerPort: 2222 - name: tfjob-port - resources: - limits: - nvidia.com/gpu: 2 - workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks - restartPolicy: OnFailure - ``` -2. 创建TFJob - ```shell script - kubectl apply -f tf-gpu.yaml - ``` -3. 在Yunikorn中验证TFJob是否运行 - ![tf-job-gpu-on-ui](../../assets/tf-job-gpu-on-ui.png) - 察看pod的日志: - ```shell script - kubectl logs logs po/tf-smoke-gpu-worker-0 -n kubeflow - ``` - ``` - ....... - ..Found device 0 with properties: - ..name: NVIDIA GeForce RTX 3080 major: 8 minor: 6 memoryClockRate(GHz): 1.71 - - ....... - ..Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: NVIDIA GeForce RTX 3080, pci bus id: 0000:01:00.0, compute capability: 8.6) - ....... - ``` - ![tf-job-gpu-on-logs](../../assets/tf-job-gpu-on-logs.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/workload_overview.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/workload_overview.md deleted file mode 100644 index c7b46a4c378..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.3.0/user_guide/workloads/workload_overview.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: workload_overview -title: 概述 ---- - - - -YuniKorn调度器支持任何的Kubernetes工作负载。所需要的只是确保将Pod规范的 -`schedulerName`字段设置为`yunikorn`并将`applicationId`标签设置为每个应用程序的唯一值: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - labels: - app: sleep - applicationId: "application-sleep-0001" - name: sleep-app-1 -spec: - schedulerName: yunikorn - containers: - - name: sleep-30s - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "100M" -``` - -此外,如果存在YuniKorn准入控制器,则可以省略“schedulerName”字段,因为它将在新创建的pod上自动设置。 - -## 进阶例子 - -可以在此处找到更进阶的例子: - -* [运行Spark作业](run_spark) -* [运行Flink作业](run_flink) -* [运行TensorFlow作业](run_tf) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/cluster.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/cluster.md deleted file mode 100644 index 48f25f82ae8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/cluster.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -id: cluster -title: 集群 ---- - - - -## 集群 - -回传 Yunikorn 所管理的集群信息,像是资源管理器的构建信息。 - -**位置(URL)** : `/ws/v1/clusters` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**回传代码**:`200 OK` - -**示例** - -在本示例中,响应的内容来自一个群集,拥有一个资源管理器。 - -```json -[ - { - "startTime": 1697100824863892713, - "rmBuildInformation": [ - { - "arch": "amd64", - "buildDate": "2023-09-04T18:11:43+0800", - "buildVersion": "latest", - "coreSHA": "0ecf24d2aad2", - "goVersion": "1.21", - "isPluginVersion": "false", - "rmId": "mycluster", - "shimSHA": "8b26c373b4b5", - "siSHA": "e7622cf54e95" - } - ], - "partition": "default", - "clusterName": "kubernetes" - } -] -``` - -### 出错时的响应 - -**回传代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/scheduler.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/scheduler.md deleted file mode 100644 index a0bbfa87144..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/scheduler.md +++ /dev/null @@ -1,1484 +0,0 @@ ---- -id: scheduler -title: 调度器 ---- - - - -# 概要 - -Yunikorn调度器能透过REST API来返回多个对象的信息 -其中许多API将回传资源集合。在内部中,所有资源被「有符号的64位整数类型」所表示。当解析REST API的响应时,类型为`memory`的资源以bytes作为单位,而`vcore`则以一千表示一个CPU核心。而这两类之外的其他资源种类则没有具体指定。 - -在与app/node相关调用的响应中,包含一个`allocations`字段,而该字段中也包含多个字段。如`placeholderUsed`指的是分配是否是取代占位符(placeholder)。如果为true,`requestTime`将代表的是占位符的创建时间,如果为false,则就是代表这个分配(allocation)被询问时的时间。`allocationTime`则为分配被创建的时间,`allocationDelay`,则为`allocationTime`和`requestTime `相差的时间。 - -## 分区(Partitions) - -显示有关分区的一般信息和统计数据。 - -**位置(URL)**:`/ws/v1/partitions` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -```json -[ - { - "clusterId": "mycluster", - "name": "default", - "state": "Active", - "lastStateTransitionTime": 1649167576110754000, - "capacity": { - "capacity": { - "ephemeral-storage": 188176871424, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 1000000000, - "pods": 330, - "vcore": 1000 - }, - "usedCapacity": { - "memory": 800000000, - "vcore": 500 - }, - "utilization": { - "memory": 80, - "vcore": 50 - } - }, - "nodeSortingPolicy": { - "type": "fair", - "resourceWeights": { - "memory": 1.5, - "vcore": 1.3 - } - }, - "applications": { - "New": 5, - "Pending": 5, - "total": 10 - }, - "totalContainers": 0, - "totalNodes": 2 - }, - { - "clusterId": "mycluster", - "name": "gpu", - "state": "Active", - "lastStateTransitionTime": 1649167576111236000, - "capacity": { - "capacity": { - "memory": 2000000000, - "vcore": 2000 - }, - "usedCapacity": { - "memory": 500000000, - "vcore": 300 - }, - "utilization": { - "memory": 25, - "vcore": 15 - } - }, - "nodeSortingPolicy": { - "type": "binpacking", - "resourceWeights": { - "memory": 0, - "vcore": 4.11 - } - }, - "applications": { - "New": 5, - "Running": 10, - "Pending": 5, - "total": 20 - }, - "totalContainers": 20, - "totalNodes": 5 - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 队列(Queues) - -### 分区队列 - -获取给定分区中的队列,及队列相关的信息,其中包含名称、状态、容量和属性。 -队列层次结构(hierarchy)被保留在响应的json档中。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/queues` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -在预设的队列层次结构中(仅`root.default`),将会向客户端发送与以下相似的响应。 - -```json -[ - { - "queuename": "root", - "status": "Active", - "maxResource": { - "ephemeral-storage": 188176871424, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 8000000000, - "pods": 330, - "vcore": 8000 - }, - "guaranteedResource": { - "memory": 54000000, - "vcore": 80 - }, - "allocatedResource": { - "memory": 54000000, - "vcore": 80 - }, - "isLeaf": "false", - "isManaged": "false", - "properties": { - "application.sort.policy": "stateaware" - }, - "parent": "", - "template": { - "maxResource": { - "memory": 8000000000, - "vcore": 8000 - }, - "guaranteedResource": { - "memory": 54000000, - "vcore": 80 - }, - "properties": { - "application.sort.policy": "stateaware" - } - }, - "partition": "default", - "children": [ - { - "queuename": "root.default", - "status": "Active", - "maxResource": { - "memory": 8000000000, - "vcore": 8000 - }, - "guaranteedResource": { - "memory": 54000000, - "vcore": 80 - }, - "allocatedResource": { - "memory": 54000000, - "vcore": 80 - }, - "isLeaf": "true", - "isManaged": "false", - "properties": { - "application.sort.policy": "stateaware" - }, - "parent": "root", - "template": null, - "children": [], - "absUsedCapacity": { - "memory": 1, - "vcore": 0 - }, - "maxRunningApps": 12, - "runningApps": 4, - "allocatingAcceptedApps": [ - "app-1", - "app-2" - ] - } - ], - "absUsedCapacity": { - "memory": 1, - "vcore": 0 - } - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 多个应用程序 - -### 队列中多个应用程序 - -获取给定分区/队列组合的所有应用程序,并显示有关应用程序的信息,如使用的资源、队列名称、提交时间和分配。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/queue/{queueName}/applications` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -在下面的示例中,有三个分配属于两个应用程序,其中一个具有挂起(Pending)的请求。 - -```json -[ - { - "applicationID": "application-0001", - "usedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "maxUsedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "partition": "default", - "queueName": "root.default", - "submissionTime": 1648754032076020293, - "requests": [ - { - "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task2" - }, - "requestTime": 16487540320812345678, - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "pendingCount": 1, - "priority": "0", - "requiredNodeId": "", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderTimeout": 0, - "taskGroupName": "", - "allocationLog": [ - { - "message": "node(s) didn't match Pod's node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate", - "lastOccurrence": 16487540320812346001, - "count": 81 - }, - { - "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346002, - "count": 504 - }, - { - "message": "node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346003, - "count": 1170 - } - ] - } - ], - "allocations": [ - { - "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": true - } - ], - "applicationState": "Running", - "user": "system:serviceaccount:kube-system:deployment-controller", - "groups": [ - "system:serviceaccounts", - "system:serviceaccounts:kube-system", - "system:authenticated" - ], - "rejectedMessage": "", - "stateLog": [ - { - "time": 1648741409145224000, - "applicationState": "Accepted" - }, - { - "time": 1648741409145509400, - "applicationState": "Starting" - }, - { - "time": 1648741409147432100, - "applicationState": "Running" - } - ], - "placeholderData": [ - { - "taskGroupName": "task-group-example", - "count": 2, - "minResource": { - "memory": 1000000000, - "vcore": 100 - }, - "replaced": 1, - "timedout": 1 - } - ] - }, - { - "applicationID": "application-0002", - "usedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "maxUsedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "partition": "default", - "queueName": "root.default", - "submissionTime": 1648754032076020293, - "requests": [], - "allocations": [ - { - "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0002", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "08033f9a-4699-403c-9204-6333856b41bd", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0002", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - }, - { - "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0002", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task1" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0002", - "applicationId": "application-0002", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - } - ], - "applicationState": "Running", - "user": "system:serviceaccount:kube-system:deployment-controller", - "groups": [ - "system:serviceaccounts", - "system:serviceaccounts:kube-system", - "system:authenticated" - ], - "rejectedMessage": "", - "stateLog": [ - { - "time": 1648741409145224000, - "applicationState": "Accepted" - }, - { - "time": 1648741409145509400, - "applicationState": "Starting" - }, - { - "time": 1648741409147432100, - "applicationState": "Running" - } - ], - "placeholderData": [] - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 单一应用程序 - -### 队列中单一应用程序 - -从给定分区、队列和应用程序ID来获取应用程序,并显示有关应用程序的信息,如使用的资源、队列名称、提交时间和分配。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/queue/{queueName}/application/{appId}` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -```json -{ - "applicationID": "application-0001", - "usedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "maxUsedResource": { - "memory": 4000000000, - "vcore": 4000 - }, - "partition": "default", - "queueName": "root.default", - "submissionTime": 1648754032076020293, - "requests": [ - { - "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task2" - }, - "requestTime": 16487540320812345678, - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "pendingCount": 1, - "priority": "0", - "requiredNodeId": "", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderTimeout": 0, - "taskGroupName": "", - "allocationLog": [ - { - "message": "node(s) didn't match Pod's node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate", - "lastOccurrence": 16487540320812346001, - "count": 81 - }, - { - "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346002, - "count": 504 - }, - { - "message": "node(s) didn't match Pod's node affinity", - "lastOccurrence": 16487540320812346003, - "count": 1170 - } - ] - } - ], - "allocations": [ - { - "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": true - } - ], - "applicationState": "Running", - "user": "system:serviceaccount:kube-system:deployment-controller", - "groups": [ - "system:serviceaccounts", - "system:serviceaccounts:kube-system", - "system:authenticated" - ], - "rejectedMessage": "", - "stateLog": [ - { - "time": 1648741409145224000, - "applicationState": "Accepted" - }, - { - "time": 1648741409145509400, - "applicationState": "Starting" - }, - { - "time": 1648741409147432100, - "applicationState": "Running" - } - ], - "placeholderData": [ - { - "taskGroupName": "task-group-example", - "count": 2, - "minResource": { - "memory": 1000000000, - "vcore": 100 - }, - "replaced": 1, - "timedout": 1 - } - ] -} -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 多个节点 - -### 分区中多个节点 - -获取给定分区的所有节点,并显示由YuniKorn管理的节点的信息。 -节点详细信息包括主机和机架名称、容量、资源、利用率和分配。 - -**位置(URL)**:`/ws/v1/partition/{partitionName}/nodes` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -这个示例的响应,来自一个群集,其中包含2个节点和3个分配。 - -```json -[ - { - "nodeID": "node-0001", - "hostName": "", - "rackName": "", - "capacity": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 14577000000, - "pods": 110, - "vcore": 10000 - }, - "allocated": { - "memory": 6000000000, - "vcore": 6000 - }, - "occupied": { - "memory": 154000000, - "vcore" :750 - }, - "available": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 6423000000, - "pods": 110, - "vcore": 1250 - }, - "utilized": { - "memory": 3, - "vcore": 13 - }, - "allocations": [ - { - "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "08033f9a-4699-403c-9204-6333856b41bd", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - }, - { - "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0002", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task0" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource": { - "memory": 4000000000, - "vcore": 4000 - }, - "priority": "0", - "nodeId": "node-0001", - "applicationId": "application-0002", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - } - ], - "schedulable": true - }, - { - "nodeID": "node-0002", - "hostName": "", - "rackName": "", - "capacity": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 14577000000, - "pods": 110, - "vcore": 10000 - }, - "allocated": { - "memory": 2000000000, - "vcore": 2000 - }, - "occupied": { - "memory": 154000000, - "vcore" :750 - }, - "available": { - "ephemeral-storage": 75850798569, - "hugepages-1Gi": 0, - "hugepages-2Mi": 0, - "memory": 6423000000, - "pods": 110, - "vcore": 1250 - }, - "utilized": { - "memory": 8, - "vcore": 38 - }, - "allocations": [ - { - "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81", - "allocationTags": { - "kubernetes.io/label/app": "sleep", - "kubernetes.io/label/applicationId": "application-0001", - "kubernetes.io/label/queue": "root.default", - "kubernetes.io/meta/namespace": "default", - "kubernetes.io/meta/podName": "task1" - }, - "requestTime": 1648754034098912461, - "allocationTime": 1648754035973982920, - "allocationDelay": 1875070459, - "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b", - "resource": { - "memory": 2000000000, - "vcore": 2000 - }, - "priority": "0", - "nodeId": "node-0002", - "applicationId": "application-0001", - "partition": "default", - "placeholder": false, - "placeholderUsed": false - } - ], - "schedulable": true - } -] -``` - -### 错误时的响应 - -**返回代码**:`500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 单一节点 - -### 分区中单一节点 - -从给定分区和节点ID来获取节点,并显示有关节点的信息,节点详细信息包括主机和机架名称、容量、资源、利用率和分配。 - -**位置(URL)** : `/ws/v1/partition/{partitionName}/node/{nodeId}` - -**方法(Method)** : `GET` - -**需求权限** : NO - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -{ - "nodeID":"node-0001", - "hostName":"", - "rackName":"", - "capacity":{ - "ephemeral-storage":75850798569, - "hugepages-1Gi":0, - "hugepages-2Mi":0, - "memory":14577000000, - "pods":110, - "vcore":10000 - }, - "allocated":{ - "memory":6000000000, - "vcore":6000 - }, - "occupied":{ - "memory":154000000, - "vcore":750 - }, - "available":{ - "ephemeral-storage":75850798569, - "hugepages-1Gi":0, - "hugepages-2Mi":0, - "memory":6423000000, - "pods":110, - "vcore":1250 - }, - "utilized":{ - "memory":3, - "vcore":13 - }, - "allocations":[ - { - "allocationKey":"54e5d77b-f4c3-4607-8038-03c9499dd99d", - "allocationTags":{ - "kubernetes.io/label/app":"sleep", - "kubernetes.io/label/applicationId":"application-0001", - "kubernetes.io/label/queue":"root.default", - "kubernetes.io/meta/namespace":"default", - "kubernetes.io/meta/podName":"task0" - }, - "requestTime":1648754034098912461, - "allocationTime":1648754035973982920, - "allocationDelay":1875070459, - "uuid":"08033f9a-4699-403c-9204-6333856b41bd", - "resource":{ - "memory":2000000000, - "vcore":2000 - }, - "priority":"0", - "nodeId":"node-0001", - "applicationId":"application-0001", - "partition":"default", - "placeholder":false, - "placeholderUsed":false - }, - { - "allocationKey":"deb12221-6b56-4fe9-87db-ebfadce9aa20", - "allocationTags":{ - "kubernetes.io/label/app":"sleep", - "kubernetes.io/label/applicationId":"application-0002", - "kubernetes.io/label/queue":"root.default", - "kubernetes.io/meta/namespace":"default", - "kubernetes.io/meta/podName":"task0" - }, - "requestTime":1648754034098912461, - "allocationTime":1648754035973982920, - "allocationDelay":1875070459, - "uuid":"9af35d44-2d6f-40d1-b51d-758859e6b8a8", - "resource":{ - "memory":4000000000, - "vcore":4000 - }, - "priority":"0", - "nodeId":"node-0001", - "applicationId":"application-0002", - "partition":"default", - "placeholder":false, - "placeholderUsed":false - } - ], - "schedulable":true -} -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## Goroutines信息 - -获取当前运行的goroutines的堆栈跟踪(stack traces) - -**位置(URL)**:`/ws/v1/stack` - -**方法(Method)**:`GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码**:`200 OK` - -**示例** - -```text -goroutine 356 [running -]: -github.com/apache/yunikorn-core/pkg/webservice.getStackInfo.func1(0x30a0060, -0xc003e900e0, -0x2) - /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 41 +0xab -github.com/apache/yunikorn-core/pkg/webservice.getStackInfo(0x30a0060, -0xc003e900e0, -0xc00029ba00) - /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 48 +0x71 -net/http.HandlerFunc.ServeHTTP(0x2df0e10, -0x30a0060, -0xc003e900e0, -0xc00029ba00) - /usr/local/go/src/net/http/server.go: 1995 +0x52 -github.com/apache/yunikorn-core/pkg/webservice.Logger.func1(0x30a0060, -0xc003e900e0, -0xc00029ba00) - /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/webservice.go: 65 +0xd4 -net/http.HandlerFunc.ServeHTTP(0xc00003a570, -0x30a0060, -0xc003e900e0, -0xc00029ba00) - /usr/local/go/src/net/http/server.go: 1995 +0x52 -github.com/gorilla/mux.(*Router).ServeHTTP(0xc00029cb40, -0x30a0060, -0xc003e900e0, -0xc0063fee00) - /yunikorn/go/pkg/mod/github.com/gorilla/mux@v1.7.3/mux.go: 212 +0x140 -net/http.serverHandler.ServeHTTP(0xc0000df520, -0x30a0060, -0xc003e900e0, -0xc0063fee00) - /usr/local/go/src/net/http/server.go: 2774 +0xcf -net/http.(*conn).serve(0xc0000eab40, -0x30a61a0, -0xc003b74000) - /usr/local/go/src/net/http/server.go: 1878 +0x812 -created by net/http.(*Server).Serve - /usr/local/go/src/net/http/server.go: 2884 +0x4c5 - -goroutine 1 [chan receive, - 26 minutes -]: -main.main() - /yunikorn/pkg/shim/main.go: 52 +0x67a - -goroutine 19 [syscall, - 26 minutes -]: -os/signal.signal_recv(0x1096f91) - /usr/local/go/src/runtime/sigqueue.go: 139 +0x9f -os/signal.loop() - /usr/local/go/src/os/signal/signal_unix.go: 23 +0x30 -created by os/signal.init.0 - /usr/local/go/src/os/signal/signal_unix.go: 29 +0x4f - -... -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 指标(Metrics) - -从Prometheus服务器检索指标的端点。 -指标中包含帮助消息和类型信息(type information)。 - -**位置(URL)** : `/ws/v1/metrics` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```text -# HELP go_gc_duration_seconds 作为垃圾收集周期的暂停期间的摘要。 -# TYPE go_gc_duration_seconds summary -go_gc_duration_seconds{quantile="0"} 2.567e-05 -go_gc_duration_seconds{quantile="0.25"} 3.5727e-05 -go_gc_duration_seconds{quantile="0.5"} 4.5144e-05 -go_gc_duration_seconds{quantile="0.75"} 6.0024e-05 -go_gc_duration_seconds{quantile="1"} 0.00022528 -go_gc_duration_seconds_sum 0.021561648 -go_gc_duration_seconds_count 436 -# HELP go_goroutines 当前存在的goroutines数量。 -# TYPE go_goroutines gauge -go_goroutines 82 -# HELP go_info 关于Golang环境的信息。 -# TYPE go_info gauge -go_info{version="go1.12.17"} 1 -# HELP go_memstats_alloc_bytes 已经被分配且正在使用的记忆体位元(bytes)数。 -# TYPE go_memstats_alloc_bytes gauge -go_memstats_alloc_bytes 9.6866248e+07 - -... - -# HELP yunikorn_scheduler_vcore_nodes_usage 节点的CPU使用量 -# TYPE yunikorn_scheduler_vcore_nodes_usage gauge -yunikorn_scheduler_vcore_nodes_usage{range="(10%, 20%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(20%,30%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(30%,40%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(40%,50%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(50%,60%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(60%,70%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(70%,80%]"} 1 -yunikorn_scheduler_vcore_nodes_usage{range="(80%,90%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="(90%,100%]"} 0 -yunikorn_scheduler_vcore_nodes_usage{range="[0,10%]"} 0 -``` - -## 配置验证 - -**位置(URL)** : `/ws/v1/validate-conf` - -**方法(Method)** : `POST` - -**需求权限**:无 - -### 成功时的响应 - -无论配置是否被允许,如果服务器能够处理请求,它都将生成一个200HTTP状态代码。 - -**返回代码** : `200 OK` - -#### 允许的配置 - -发送以下简单配置会被接受 - -```yaml -partitions: - - name: default - queues: - - name: root - queues: - - name: test -``` - -返回 - -```json -{ - "allowed": true, - "reason": "" -} -``` - -#### 不允许的配置 - -由于以下的的yaml档案中包含了“wrong_text”字段,因此是不允许的配置。 - -```yaml -partitions: - - name: default - queues: - - name: root - queues: - - name: test - - wrong_text -``` - -返回 - -```json -{ - "allowed": false, - "reason": "yaml: unmarshal errors:\n line 7: cannot unmarshal !!str `wrong_text` into configs.PartitionConfig" -} -``` - -## 配置 - -检索当前调度器配置的端点 - -**位置(URL)** : `/ws/v1/config` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```yaml -partitions: -- name: default - queues: - - name: root - parent: true - submitacl: '*' - placementrules: - - name: tag - create: true - value: namespace -checksum: D75996C07D5167F41B33E27CCFAEF1D5C55BE3C00EE6526A7ABDF8435DB4078E -``` - -## 应用程序历史 - -检索历史数据的端点,依据时间来条列应用程序的总数。 - -**位置(URL)** : `/ws/v1/history/apps` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -[ - { - "timestamp": 1595939966153460000, - "totalApplications": "1" - }, - { - "timestamp": 1595940026152892000, - "totalApplications": "1" - }, - { - "timestamp": 1595940086153799000, - "totalApplications": "2" - }, - { - "timestamp": 1595940146154497000, - "totalApplications": "2" - }, - { - "timestamp": 1595940206155187000, - "totalApplications": "2" - } -] -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - -## 容器历史 - -检索历史数据的端点,依据时间来条列容器的总数。 - -**位置(URL)** : `/ws/v1/history/containers` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -[ - { - "timestamp": 1595939966153460000, - "totalContainers": "1" - }, - { - "timestamp": 1595940026152892000, - "totalContainers": "1" - }, - { - "timestamp": 1595940086153799000, - "totalContainers": "3" - }, - { - "timestamp": 1595940146154497000, - "totalContainers": "3" - }, - { - "timestamp": 1595940206155187000, - "totalContainers": "3" - } -] -``` - -### 错误时的响应 - -**返回代码** : `500 Internal Server Error` - -**示例** - -```json -{ - "status_code": 500, - "message": "system error message. for example, json: invalid UTF-8 in string: ..", - "description": "system error message. for example, json: invalid UTF-8 in string: .." -} -``` - - -## 健康检查的端点 - -用来检索历史数据的端点,其中包含关键日志,以及节点、集群、应用程序中资源量为负的资源。 - -**位置(URL)** : `/ws/v1/scheduler/healthcheck` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -```json -{ - "Healthy": true, - "HealthChecks": [ - { - "Name": "Scheduling errors", - "Succeeded": true, - "Description": "Check for scheduling error entries in metrics", - "DiagnosisMessage": "There were 0 scheduling errors logged in the metrics" - }, - { - "Name": "Failed nodes", - "Succeeded": true, - "Description": "Check for failed nodes entries in metrics", - "DiagnosisMessage": "There were 0 failed nodes logged in the metrics" - }, - { - "Name": "Negative resources", - "Succeeded": true, - "Description": "Check for negative resources in the partitions", - "DiagnosisMessage": "Partitions with negative resources: []" - }, - { - "Name": "Negative resources", - "Succeeded": true, - "Description": "Check for negative resources in the nodes", - "DiagnosisMessage": "Nodes with negative resources: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if a node's allocated resource <= total resource of the node", - "DiagnosisMessage": "Nodes with inconsistent data: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if total partition resource == sum of the node resources from the partition", - "DiagnosisMessage": "Partitions with inconsistent data: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if node total resource = allocated resource + occupied resource + available resource", - "DiagnosisMessage": "Nodes with inconsistent data: []" - }, - { - "Name": "Consistency of data", - "Succeeded": true, - "Description": "Check if node capacity >= allocated resources on the node", - "DiagnosisMessage": "Nodes with inconsistent data: []" - }, - { - "Name": "Reservation check", - "Succeeded": true, - "Description": "Check the reservation nr compared to the number of nodes", - "DiagnosisMessage": "Reservation/node nr ratio: [0.000000]" - } - ] -} -``` - -## 检索所有状态 - -能在单一响应包含以下的信息: - -* 分区清单 -* 应用程序清单(`运行中` 和 `已完成`) -* 应用程序历史 -* 节点 -* 节点的使用率 -* 集群的基本信息 -* 集群的使用率 -* 容器的历史 -* 队列 -* RM 诊断 - -**位置(URL)** : `/ws/v1/fullstatedump` - -**方法(Method)** : `GET` - -**需求权限**:无 - -### 成功时的响应 - -**返回代码** : `200 OK` - -**示例** - -该REST请求的输出将会很巨大,且为前面演示过的输出的组合。 - -RM 诊断显示 K8Shim 缓存的内容。确切内容取决于版本并且尚未稳定。 -当前内容显示缓存的对象: -* 节点 -* pods -* 优先等级 -* 调度状态(pod状态) - -### 错误时的响应 - -**代码**:`500 Internal Server Error` - -## 启用或禁用定期写入状态信息 - -为允许状态周期性地写入的端点。 - -**状态**:自v1.2.0以来已弃用并被忽略,无替代品。 - -**位置(URL)** : `/ws/v1/periodicstatedump/{switch}/{periodSeconds}` - -**方法(Method)** : `PUT` - -**需求权限**:无 - -### 成功时的响应 - -无 - -### 错误时的响应 - -**代码**: `400 Bad Request` - -## 获取日志级别 -接收当前Yunikorn的日志级别。 - -**URL** : `/ws/v1/loglevel` - -**方法** : `GET` - -**需求权限** : 无 - -### 成功时的响应 - -**代码**: `200 OK` - -**示例** - -``` -info% -``` - -## 设置日志级别 -设置Yunikorn日志级别。 - -**URL** : `/ws/v1/loglevel/{level}` - -**方法** : `PUT` - -**需求权限** : NO - -### 成功时的响应 - -**代码**: `200 OK` - -### 错误时的响应 - -**代码**: `400 Bad Request` - -**示例** - -```json -{ - "status_code":400, - "message":"failed to change log level, old level active", - "description":"failed to change log level, old level active" -} -``` - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/system.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/system.md deleted file mode 100644 index 83337cf4bc3..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/api/system.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -id: system -title: 系統 ---- - - - -这些端点是用于提供資訊給[pprof](https://github.com/google/pprof)分析工具。 - -## pprof - -**位置(URL)** : `/debug/pprof/` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```text -/debug/pprof/ - -Types of profiles available: -Count Profile -273 allocs -0 block -0 cmdline -78 goroutine -273 heap -0 mutex -0 profile -29 threadcreate -0 trace -full goroutine stack dump -Profile Descriptions: - -allocs: A sampling of all past memory allocations -block: Stack traces that led to blocking on synchronization primitives -cmdline: The command line invocation of the current program -goroutine: Stack traces of all current goroutines -heap: A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample. -mutex: Stack traces of holders of contended mutexes -profile: CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile. -threadcreate: Stack traces that led to the creation of new OS threads -trace: A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace. -``` - -## 堆 (Heap) - -**位置(URL)** : `/debug/pprof/heap` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 线程创建 - -**位置(URL)** : `/debug/pprof/threadcreate` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## Goroutine - -**位置(URL)** : `/debug/pprof/goroutine` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 分配 (Allocations) - -**位置(URL)** : `/debug/pprof/allocs` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 阻塞分析 (Block) - -**位置(URL)** : `/debug/pprof/block` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 互斥锁分析 (Mutex) - -**位置(URL)** : `/debug/pprof/mutex` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 命令行参数 (Cmdline) - -**位置(URL)** : `/debug/pprof/cmdline` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 简介 - -**位置(URL)** : `/debug/pprof/profile` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## Symbol - -**位置(URL)** : `/debug/pprof/symbol` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` - -## 跟踪(Trace) - -**位置(URL)** : `/debug/pprof/trace` - -**方法(Method)** : `GET` - -### 成功时的响应 - -**回传代码** : `200 OK` - -**示例** - -```proto -// 来自proto的二进制数据 -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/assets b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/assets deleted file mode 120000 index 778d0f8e471..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/assets +++ /dev/null @@ -1 +0,0 @@ -../../../../docs/assets \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/design/scheduler_plugin.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/design/scheduler_plugin.md deleted file mode 100644 index 6656625d099..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/design/scheduler_plugin.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: scheduler_plugin -title: K8s 调度器插件 ---- - - - - -## 背景 - -在 Kubernetes 上,原始的作法是将 YuniKorn 当作 Kubernetes 调度器从零开始实现的。这使我们能够快创新,但也存在问题。我们目前有许多地方 -调用非公开的 K8S 源代码API,这些API的稳定性各不相同,当我们切换到新的 Kubernetes 版本时,需要进行破坏性的代码更动。 - -理想情况下,我们应该能够自动地支援新的 Kubernetes 发布版本,并受益于新功能。使用插件模式可以增强 Kubernetes 版本的兼容性,减少工作量。 -此外,在许多情况下,允许非批次处理工作负载绕过 YuniKorn 调度功能并使用默认调度逻辑是可取的。然而,我们目前无法做到这一点,因为 -YuniKorn 调度器二进制文件中没有默认的调度功能。自 Kubernetes 1.19 版本以来,Kubernetes 项目已经创建了一个稳定的 API -用于[调度框架](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/), -允许创建实现各种扩展点的插件。插件实现一个或多个这些扩展点,然后编译为调度器的二进制文件,其中包含默认调度器和差件代码, -并在正常调度流程中调用插件。 - -## 设计 - -我们在 k8s-shim 代码库中添加了一个调度器插件,可以用来编译为 Kubernetes 调度器,其中包含 YuniKorn 功能以及默认调度器功能。 -显著地提高 YuniKorn 与 Kubernetes 的兼容性,并有更大的信心将 YuniKorn 部署为集群中唯一的调度器。将为调度器建构分别两种 Docker 镜像: -传统的 YuniKorn 调度器构建为 `scheduler-{version}`,而新的插件版本构建为 `scheduler-plugin-{version}`。可以通过自定义调度器镜像 -来交替部署它们到 Kubernetes 集群中,使用相同的 Helm charts 进行部署。 - -## 入口点 - -现有的 shim `main()` 方法已经被移动到 `pkg/cmd/shim/main.go`,并创建了一个新的 `main()` 方法在 -`pkg/cmd/schedulerplugin/main.go` 之下。该方法实例化默认的 Kubernetes 调度器,并将 YuniKorn 作为一组插件添加到其中。 -它还修改了默认调度器器的 CLI 参数解析,以添加 YuniKorn 特定的选项。创建 YuniKorn 插件时,它将在后台启动现有的 shim / core 调度器, -同步所有的 informer, 并启动正常的 YuniKorn 调度循环。 - -## Shim 调度器更改 - -为了与默认调度器合作,当处于插件模式时,shim 需要稍微不同地操作。这些差异包括: - -- 在 `postTaskAllocated()` 中,我们实际上不会绑定 Pod 或 Volumes,因为这是默认调度器框架的责任。 - 相反,我们在内部映射中跟踪 YK 为节点分配的节点,分派一个新的 BindTaskEvent,并在 Pod 上记录一个 `QuotaApproved` 事件。 -- 在 `postTaskBound()` 中,我们将 Pod 的状态更新为 `QuotaApproved`,因为这将导致默认调度器重新评估 Pod 的调度(更多细节见下文)。 -- 在调度器缓存中,我们跟踪待处理和进行中的 Pod 分配。当 Pod 在 Kubernetes 中被删除时,也将调度器缓存中的 Pod 删除。 - - -## 插件模式的实现 - -为了暴露 YuniKorn 的全部功能,我们实现了三个调度框架插件: - -### PreFilter - -PreFilter 插件被传入一个 Pod 的引用,并根据是否应该考虑该 Pod 进行调度,返回 `Success` 或 `Unschedulable`。 - -对于 YuniKorn 的实现,我们首先检查 Pod 是否定义 `applicationId`。如果没有,我们立即返回 `Success`, -这允许我们将非批处理工作负载委托给默认调度器。 - -如果存在 `applicationId`,则确定是否存在待处理的 Pod 分配(表示 YuniKorn core 已经决定分配该 Pod)。 -如果存在待处理的 Pod 分配,我们返回 `Success`,否则返回 `Unschedulable`。 -此外,如果检测到正在进行的分配(表示我们先前尝试过调度该 Pod),我们触发一个 `RejectTask` 事件给 YuniKorn core, -以便稍后重新发送该 Pod 进行调度。 - -### Filter - -Filter 插件用于过滤无法运行 Pod 的节点。只有在 PreFilter 阶段通过的 Pod 才会进行评估。 - -对于 YuniKorn 插件,我们遵循类似 PreFilter 的逻辑,但我们还验证「待处理的 Pod 分配」之节点是否与 YuniKorn 选择的节点匹配。 -如果节点匹配,我们将待处理分配转换为进行中的分配。这样做的目的是确保与默认调度器保持同步。因为有可能我们允许分配继续进行, -但由于某些原因导致绑定失败。这样的处理方式有助于保持一致性。 - -### PostBind - -PostBind 扩展点在信息上用于通知插件一个 Pod 已成功绑定。 - -YuniKorn 使用这个来清理未完成的Pod分配进程。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/design/simple_preemptor.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/design/simple_preemptor.md deleted file mode 100644 index 7dbce187c71..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/design/simple_preemptor.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -id: simple_preemptor -title: DaemonSet Scheduling using Simple Preemptor ---- - - -# Design & Implementation of Preemption for DaemonSet Pods using Simple Preemptor - -The simplistic approach to preempt or free up resources of running applications for DaemonSet pods. A good example of daemonset pod is fluentd logging pod which is very essential for any applicaton pod running in the node for logging. - -## When to start preemption? -[YUNIKORN-1184](https://issues.apache.org/jira/browse/YUNIKORN-1184) ensures daemon set pods have been allocated properly if resources are available on the required node, otherwise, reserve the same required node so that it can be picked up to make reservation as reserved allocation (AllocatedReserved) in the next scheduling cycle. However, the whole process of modifying the reservation to reserved allocation depends on how much resources are freed up in the meantime. Duration for freeing up resources by natural course is non deterministic as it depends on the running pods execution on that particular node and it could take slightly longer time as well. - -By any chance, before the next run of the regular scheduling cycle (context#schedule() ), resources become available and particularly on that specific required node, then nothing needs to be done. It just moves ahead with the next steps. In case of resource constraints, unlike the regular pod reservation, other nodes cannot be tried by calling application#tryNodesNoReserve() as this demonset pod needs to run only on the specific required node. Instead, we can fork a new go routine (trigger_preempt_workflow() ) to run the workflow steps described below. - - -## How to do preemption? -K8s does the preemption based on the pod priority. Pods with lower priority would be chosen first and so on. Proposal is not to depend on k8s for Preemption. Instead, Core should take the responsibility of finding out the list of pods that needs to be preempted, making communications to Shim and finally expecting the preempted resources to allocate to the corresponding daemonset automatically as part of the regular scheduling cycle. - -### Steps in trigger_preempt_workflow() go routine: - -##### Reservation age check (1) -We can introduce a new Reservation age “createtime” (can be added to the reservation object) to check against the configured value of preemption_start_delay, a property to define the minimal waiting time to start the preemption process. Once reservation age exceeds this waiting time, the next step would be carried out. Otherwise, the corresponding reservation has to wait and can be processed next time. - -##### Get allocations from specific required Node (2) -Get all allocations from the required node of the daemonset pod and go through the below Pre-filter pods step to filter the pods not suited for a preemption. - -##### Pre-filter pods to choose Victims/Candidates suited for Preemption (3) - -Core should filter the pods based on the following criteria: - -###### DaemonSet Pods - -All Daemonset pods should be filtered out completely irrespective of priority settings. Depending on the “requiredNode” value of pod spec, these pods can be filtered out and cannot be taken forward for the remaining process. - -![simple_preemptor](./../assets/simple_preemptor.png) - -##### Ordering Victim pods (4) - -###### Pods classification - -Once pods has been filtered out, need to classify the pods based on its types: - -1. Regular/Normal Pods (RP) -2. Driver/Owner Pods (DP) -3. Preemption Opt out Pods (OP) - -This classification ensures different treatment for each type of pod so that victims can be chosen among these pods in the same order. Please refer to the above diagram. It shows the 2-Dimensional array (NOTE: “Array” has been used only for documentation purposes, need to finalize the appropriate data structure) with each sub array holding pods of the same type. 1st sub array has RP’s, 2nd sub array has DP’s, 3rd sub array has OP’s and goes on. - -Regular/Normal Pods (RP) - -The regular/normal pods should be gathered and placed in the 1st sub array as these pods are given first preference for choosing the victims. In general, preempting these pods have very little impact when compared to other types/classes of pods. Hence, keeping these pods in the first subarray is the right choice - -Application Owner (DP) - -Pod acting as owner/master for other pods in the same application should be placed in the 2nd sub array because preempting those kinds of pods has a major impact when compared to Regular pods. We can select these pods by checking whether any owner reference exists between this pod and other pods. This will help prevent scenarios such as a driver pod being evicted at a very early stage when other alternatives are available for choosing the victim. - -Preemption Opt out (OP) - -Pods can be allowed to run with the Preempt opt out option. So, Pods marked with opt out should be placed in the 3rd sub array and can be used to choose victims as a last option. For now, we can use a label such as yunikorn.apache.org/allow-preemption: false for detecting those pods. - - -As and when we want to introduce a new class/type of Pods, a new sub array would be created for the same and would be placed in the main array based on its significance. - -###### Sorting Pods - -Each sub array should be sorted based on the multiple criteria: - -1. Priority -2. Age -3. Resource - -Each sub array would be sorted priority wise, age wise and finally resource wise. The 1st sub array carrying Regular Pods has 4 pods of priority 1 and 2 pods of Priority 2. Among the 4 pods of the same priority, 3 pods are of the same age as well. Hence, again sorting resource wise really adds value and sorts them in the above shown order. Please refer to “zone”. - -#### Victim pods selection strategy (5) - -Introduce a new configuration, preemption_victim_poselection_strategy with different options (single, multiple etc) but later options act as fallback to earlier one. Defining an order for these options should be possible and upto the Administrator to place the options in an order he/she desires. Depending on the values, the whole selection strategy mechanism can decide whether a “fallback” approach among these options should be followed or not. Depending on the value, the selection strategy process would continue with the next option only if no selection has been made with the earlier option or stop only with the first option even if no selection has been made. - -##### 1. Single Victim Pod - -Single Victim Pod, but resource deviation between victim pod and daemonset pod is not beyond configurable percentage. Configuring deviation with lower percentage (for example, 5% or 10%) helps prevent evicting victim pods already running with higher resource requirements. If there are many single victims found within the defined deviation %, then selection starts based on deviation % ascending order as intent is to choose the victim as close as possible to the daemonset pod resource requirements. - -##### 2. Multiple Victim Pods - -Multiple Victim Pods, but no. of victim pods not more than configured value. This selection strategy helps to choose more than one victim, starts with the victim (resource wise descending order) and goes upto to a stage where total resource of victims meets the daemonset resource requirements but ensuring total count of victim pods not exceeding configured value. - -New config: preemption_victim_pods_selection_strategy -Possible values are single,multiple (default) or multiple,single or single or multiple - -In case of more than one value (for ex. single,multiple), fallback would be followed as described above. - -#### Communicate the Pod Preemption to Shim (6) - -Once the list of pods has been finalized for preemption, Core can make a call to Shim for termination using notifyRMAllocationReleased (with type as TerminationType_PREEMPTED_BY_SCHEDULER). Shim can process the request as usual by making a call to K8s to delete the pod and subsequently call failTaskPodWithReasonAndMsg to notify the pod with reasons. - -### What happens after Preemption? - -Shim makes a call to K8s to delete the pod. Once k8s delete the pod, shim gets a notification from k8 and passes the information to core. This flow happens for any pod deletion and exists even today. So, even for preempted resources, we can leave it upto the regular scheduling cycle and Core-Shim communications to allocate these freed up preempted resources to the daemonset pod as node has been already reserved much earlier before the above described whole preemption workflow has begun. \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/build.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/build.md deleted file mode 100644 index c1e3803819a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/build.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: build -title: 建构和运行 ---- - - - -YuniKorn始终与容器编排系统一起使用。目前,在我们的存储库中提供了一个Kubernetes适配器[yunikorn-k8shim](https://github.com/apache/yunikorn-k8shim),您可以利用它来开发YuniKorn调度功能并与Kubernetes集成。本文档描述了如何设置开发环境以及如何进行开发。 - -## 开发环境设置 - -首先阅读[环境设置指南](developer_guide/env_setup.md)以设置Docker和Kubernetes开发环境。 - -## 为Kubernetes构建YuniKorn - -先决条件: -- Golang: 在存储库的根目录中检查 `.go_version` 文件以获取Yunikorn所需的版本。最低版本可能会根据发布分支而变化。较早的Go版本可能会导致编译问题。 - -您可以从 [yunikorn-k8shim](https://github.com/apache/yunikorn-k8shim) 项目构建用于Kubernetes的调度器。 -构建过程将所有组件构建为一个可部署并在Kubernetes上运行的单个可执行文件。 - -通过拉取 `yunikorn-k8shim` 存储库来启动集成构建过程: -```bash -mkdir $HOME/yunikorn/ -cd $HOME/yunikorn/ -git clone https://github.com/apache/yunikorn-k8shim.git -``` -此时,您已经拥有一个允许您构建YuniKorn调度器的集成映像的环境。 - -### 关于Go模块和Git版本的说明 -Go使用Git来获取模块信息。 -如果用于构建的计算机上安装的Git版本较旧,可能无法检索某些模块。 -当首次尝试构建时,可能会记录类似于下面的消息: -```text -go: finding modernc.org/mathutil@v1.0.0 -go: modernc.org/golex@v1.0.0: git fetch -f origin refs/heads/*:refs/heads/* refs/tags/*:refs/tags/* in : exit status 128: - error: RPC failed; result=22, HTTP code = 404 - fatal: The remote end hung up unexpectedly -``` -要解决此问题,请将Git更新到较新的版本。 -已知Git版本1.22或更高版本可以正常工作。 - -### 构建Docker镜像 - -可以通过以下命令触发构建Docker镜像。 - -``` -make image -``` - -带有内置配置的镜像可以直接部署到Kubernetes上。 -可以在 [deployments](https://github.com/apache/yunikorn-k8shim/tree/master/deployments/scheduler) 目录下找到一些示例部署。 -对于使用ConfigMap的部署,您需要在Kubernetes中设置ConfigMap。 -如何使用ConfigMap部署调度器在 [scheduler configuration deployment](developer_guide/deployment.md) 文档中有详细说明。 - -镜像构建命令首先会构建集成可执行文件,然后创建Docker镜像。 -如果您想使用基于发布的预构建镜像,请检查 [Docker Hub repo](https://hub.docker.com/r/apache/yunikorn). - -默认的镜像标签不适用于部署到可访问存储库,因为它使用了硬编码的用户并且会使用正确的凭据推送到Docker Hub。 -您必须更新`Makefile`中的`TAG`变量以推送到可访问存储库。 -在更新镜像标签时,请注意,所提供的部署示例也需要相应更新以反映相同的更改 - -### 检查 Docker 镜像 - -之前构建的Docker镜像包含了一些重要的构建信息,您可以使用Docker的inspect命令来检索这些信息。 - -``` -docker inspect apache/yunikorn:scheduler-amd64-latest -``` - -`amd64`标签取决于您的主机架构(例如,对于`Intel`,它将是`amd64`,对于`Mac M1`,它将是`arm64`)。 - -这些信息包括每个组件的`git`修订版(最后的提交`SHA`),以帮助您了解此镜像中包含的源代码版本。它们以 `Docker` 镜像的`标签`形式列出,例如: - -``` -"Labels": { - "BuildTimeStamp": "2019-07-16T23:08:06+0800", - "Version": "0.1", - "yunikorn-core-revision": "dca66c7e5a9e", - "yunikorn-k8shim-revision": "bed60f720b28", - "yunikorn-scheduler-interface-revision": "3df392eded1f" -} -``` - -### 依赖关系 - -项目中的依赖关系使用[Go模块](https://blog.golang.org/using-go-modules)来管理。 -Go模块要求在开发系统上至少安装Go版本1.11。 - -如果您想在本地修改其中一个项目并使用本地依赖关系进行构建,您需要更改模块文件。 -更改依赖关系使用`replace`指令,如 [Update dependencies](#updating-dependencies)中所述。 - -YuniKorn项目有四个存储库,其中三个存储库在Go级别有依赖关系。 -这些依赖关系是Go模块的一部分,指向GitHub存储库。 -在开发周期中,可能需要打破对GitHub提交版本的依赖关系。 -这需要更改模块文件,以允许加载本地副本或从不同存储库中分叉的副本。 - -#### 受影响的存储库 -以下存储库之间存在依赖关系: - -| repository| depends on | -| --- | --- | -| yunikorn-core | yunikorn-scheduler-interface | -| yunikorn-k8shim | yunikorn-scheduler-interface, yunikorn-core | -| yunikorn-scheduler-interface | none | -| yunikorn-web | yunikorn-core | - -`yunikorn-web` 存储库不直接依赖于其他存储库的Go模块。但是,对 `yunikorn-core` 的webservices进行的任何更改都可能影响Web界面。 - -#### 进行本地更改 - -为了确保本地更改不会破坏构建的其他部分,您应该执行以下操作: -- 进行完整构建 `make`(构建目标取决于存储库) -- 运行完整的单元测试 `make test` - -应该在继续之前修复任何测试失败。 - -#### 更新依赖关系 - -最简单的方法是在模块文件中使用`replace`指令。`replace`指令允许您使用新的(本地)路径覆盖导入路径。 -不需要更改源代码中的任何导入。更改必须在具有依赖关系的存储库的`go.mod`文件中进行。 - -使用`replace`来使用分叉的依赖关系,例如: -``` -replace github.com/apache/yunikorn-core => example.com/some/forked-yunikorn -``` - -没有必要分叉并创建新的存储库。如果您没有存储库,也可以使用本地检出的副本。 -使用`replace`来使用本地目录作为依赖关系: -``` -replace github.com/apache/yunikorn-core => /User/example/local/checked-out-yunikorn -``` -对于相同的依赖关系,使用相对路径: -``` -replace github.com/apache/yunikorn-core => ../checked-out-yunikorn -``` -注意:如果`replace`指令使用本地文件系统路径,那么目标路径必须具有该位置的`go.mod`文件。 - -有关模块的更多详细信息,请参阅模块的维基页面。: [When should I use the 'replace' directive?](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive). - -## 构建Web用户界面(UI) - -示例部署引用了[YuniKorn Web用户界面](https://github.com/apache/yunikorn-web)。 -`yunikorn-web` 项目对构建有特定要求。请按照[README](https://github.com/apache/yunikorn-web/blob/master/README.md)中的步骤准备开发环境并构建Web用户界面(UI)。然而,调度器在没有Web用户界面的情况下仍然可以完全正常运作。 - -## 在本地运行集成调度器 - -在您设置好本地开发环境后,可以在本地的Kubernetes环境中运行集成调度器。 -这已在桌面环境中进行了测试,包括Docker Desktop、Minikube和Kind。有关更多详细信息,请参阅[环境设置指南](developer_guide/env_setup.md)。 - -``` -make run -``` -它将使用用户配置的配置文件,位于 `$HOME/.kube/config` 中,连接到Kubernetes集群。 - -要以Kubernetes调度器插件模式运行YuniKorn,执行: - -``` -make run_plugin -``` - -只要`$HOME/.kube/config`文件指向远程集群,您也可以使用相同的方法在本地运行调度器并连接到远程Kubernetes集群。 - -## 通过端到端测试验证外部接口更改 - -Yunikorn具有外部REST接口,由端到端测试验证。但是,这些测试存在于k8shim存储库中。 -每当对外部接口进行更改时,请确保通过运行端到端测试进行验证,或者相应地调整测试用例。 - -如何在本地运行测试的说明已经在文档中描述。[here](https://github.com/apache/yunikorn-k8shim/blob/master/test/e2e/README.md). \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/dependencies.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/dependencies.md deleted file mode 100644 index f270328664f..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/dependencies.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -id: dependencies -title: Go 模块更新 ---- - - - -## 什么时候更新 -如果调度器接口发生更改,则必须更新`master`分支中的引用。 -即使调度器接口没有改变,也可能需要更新shim的引用中,对core的依赖关系。 -可以添加依赖于消息的更改字段内容而不是消息的字段布局的新功能。在这种情况下,只需要更新shim依赖项。 - -## 为什么是伪版本 -在`master`分支中,我们**必须**对我们使用的所有 YuniKorn 存储库引用使用伪版本。 -由于该分支正在积极开发中并且尚未发布,因此我们没有真正的版本标签可供引用。 -但是,我们仍然需要能够指向依赖项的正确提交。 -Go 允许在这些特定情况下使用[伪版本](https://go.dev/ref/mod#pseudo-versions)。 -我们在 Kubernetes shim 中使用的伪版本的示例: -``` -module github.com/apache/yunikorn-k8shim - -go 1.16 - -require ( - github.com/apache/yunikorn-core v0.0.0-20220325135453-73d55282f052 - github.com/apache/yunikorn-scheduler-interface v0.0.0-20220325134135-4a644b388bc4 - ... -) -``` -发布分支**不得**使用伪版本。 -在创建版本的过程中,将创建[标签](/community/release_procedure#tag-and-update-release-for-version)。 -这些标签将用作该版本的 go.mod 文件中的参考。 - -## 伪版本的执行 -在拉取请求中,检查 `yunikorn-core` 和 `yunikorn-k8shim` 存储库强制执行版本格式。 -如果`master`分支中 `yunikorn-core` 或 `yunikorn-scheduler-interface` 存储库的版本引用不是伪版本,则会触发构建失败。 - -该检查强制版本引用的开头为`v.0.0.0-` - - -根据上面的[为什么是伪版本](#why-a-pseudo-version)解释,伪版本不会在发布分支中强制执行。 - -## 更新core依赖 -在更新core依赖项之前,必须确保调度器接口更改已完成。 -1. 在调度器界面中进行更改。 -2. 将更改提交到 GitHub 上的 master 分支并拉取最新的 master 分支提交。 -3. 为调度器接口[生成新的伪版本](#generate-a-pseudo-version)。 - -更新core依赖 - -4. 更新依赖存储库的go.mod文件:core存储库 - * 打开go.mod文件 - * 复制生成的伪版本引用 - * 将调度器接口版本引用替换为**步骤 3**中生成的版本引用 - * 保存go.mod文件 -5. 运行`make test`以确保更改有效。构建将拉取新的依赖项,并且将使用调度器接口中的更改。 -6. 将更改提交到 GitHub 上的 master 分支并拉取最新的 master 分支提交。 - -## 更新shim依赖项 -在更新 shim 依赖项之前,您必须确保core依赖项已更新并提交。 -在某些情况下,调度器接口的引用没有改变。 -这不是问题,要么跳过更新步骤,要么按照正常执行更新步骤,从而在提交过程中不会发生任何更改。 - -7. 为core[生成新的伪版本](#generate-a-pseudo-version) -8. 更新依赖存储库的go.mod文件:k8shim存储库 - * 打开go.mod文件 - * 复制生成的调度器接口的伪版本引用 - * 将调度器接口版本引用替换为**步骤 3**中生成的版本引用。 - * 复制生成的core伪版本引用 - * 将core版本引用替换为**步骤 7**中生成的版本引用。 - * 保存go.mod文件 -9. 运行`make test`以确保更改有效。构建将拉下新的依赖项,并将使用core和调度器接口中的更改。 -10. 将更改提交到 GitHub 上的 master 分支 - -:::note -如果同时在调度器接口和/或core中处理多个 PR,则不同的 PR 可能已经应用了更新。 -这完全取决于提交顺序。 -因此,执行**步骤 5**和**步骤 8**以确保不存在回归。 -::: -## 生成伪版本 - -go.mod 文件中使用的伪引用基于提交hash和时间戳。 -使用以下步骤生成一个很简单: - -1. 更改为需要生成新伪版本的存储库。 -2. 更新master分支的本地检查代码以获取最新提交 -``` -git pull; git status -``` - -状态应显示为最新的克隆位置的`origin`。 - -3. 运行以下命令获取伪版本: -``` -TZ=UTC git --no-pager show --quiet --abbrev=12 --date='format-local:%Y%m%d%H%M%S' --format='v0.0.0-%cd-%h' -``` -4. 该命令将打印如下一行: -``` -v0.0.0-20220318052402-b3dfd0d2adaa -``` -这是可以在 go.mod 文件中使用的伪版本。 - -:::note -伪版本必须基于 vcs 系统中的提交,即来自 Github 的提交。 -无法使用本地提交或尚未合并到 PR 中的提交。 -::: diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/env_setup.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/env_setup.md deleted file mode 100644 index 6881849d694..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/env_setup.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: env_setup -title: 开发环境的设置 ---- - - - -有很多种方法可以在本地设置Kubernetes开发环境,其中最常见的三种方法是`Minikube`([docs](https://kubernetes.io/docs/setup/minikube/))、`docker-desktop`和`kind`([kind](https://kind.sigs.k8s.io/) -`Minikube`通过数个虚拟机提供一个本地Kubernetes集群(通过VirtualBox或类似的东西)。`docker-desktop`能在docker容器中设置Kubernetes集群。 `kind`为Windows、Linux和Mac提供轻量级的Kubernetes集群。 - -## 使用Docker Desktop设置本地的Kubernetes集群 - -在本教程中,我们将基于Docker Desktop进行所有的安装。 -我们也可以使用轻量级的[minikube](#使用minikube设置本地的kubernetes集群)设置,它可以提供同样的功能,且需要的资源较小。 - -### 安装 - -在你的笔记本电脑上下载并安装[Docker-Desktop](https://www.docker.com/products/docker-desktop)。其中,最新版本包含了Kubernetes,所以不需要额外安装。 -只需按照[这里](https://docs.docker.com/docker-for-mac/#kubernetes)的步骤,就可以在docker-desktop中启动和运行Kubernetes。 - -一旦Kubernetes在docker桌面中启动,你应该看到类似以下的画面: - -![Kubernetes in Docker Desktop](./../assets/docker-desktop.png) - -这意味着: -1. Kubernetes正在运行。 -2. 命令行工具`kubctl`安装在`/usr/local/bin`目录下。 -3. Kubernetes的被设置到`docker-desktop`中。 - -### 部署和访问仪表板 - -设置好本地Kubernetes后,你需要使用以下步骤部署仪表盘: -1. 按照[Kubernetes dashboard doc](https://github.com/kubernetes/dashboard)中的说明来部署仪表盘。 -2. 从终端启动Kubernetes代理,让我们能存取本地主机上的仪表板: - ```shell script - kubectl proxy & - ``` -3. 通过以下网址访问仪表板: [链接](http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login) - -### 访问本地Kubernetes集群 - -上一步部署的仪表板需要一个令牌或配置来登录。这里我们使用令牌来登录。该令牌是自动生成的,可以从系统中检索到。 - -1. 检索仪表板令牌的名称: - ```shell script - kubectl -n kube-system get secret | grep kubernetes-dashboard-token - ``` -2. 检索令牌的内容,注意令牌名称以随机的5个字符代码结尾,需要用步骤1的结果替换。例如: - ```shell script - kubectl -n kube-system describe secret kubernetes-dashboard-token-tf6n8 - ``` -3. 複製`Data`中标签为 `token`的值。 -4. 在用户介面仪表板中选择 **Token**:
- ![Token Access in dashboard](./../assets/dashboard_token_select.png) -5. 在输入框中粘贴`token`的值,然后登录:
- ![Token Access in dashboard](./../assets/dashboard_secret.png) - -## 使用Minikube设置本地的Kubernetes集群 - -Minikube 可以被添加到现有的 Docker Desktop 中。Minikube 既可以使用预装的虚拟机管理程序(hypervisor),也可以自己选择。预设是由[HyperKit](https://github.com/moby/hyperkit)所提供的虚拟化,它已被嵌入到 Docker Desktop 中。 - -如果你不想使用 HyperKit 的虚拟机管理程序,请确保你遵循通用的minikube安装说明。如果需要的话,不要忘记为所选择的虚拟机管理程序安装正确的驱动程序。 -基本说明在[minikube install](https://kubernetes.io/docs/tasks/tools/install-minikube/)中提供。 - -如果要检查 Docker Desktop 是否安装了 HyperKit。在终端上运行: `hyperkit`来确认。除了 `hyperkit: command not found` 以外的任何响应都证实了 HyperKit 已经安装并且在路径上。如果没有找到,你可以选择一个不同的虚拟机管理程序或修复Docker Desktop。 - -### 安装 Minikube -1. 你可以使用 brew 或是以下的步骤来安装 minikube: - ```shell script - curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 - chmod +x minikube - sudo mv minikube /usr/local/bin - ``` -2. 你可以使用 brew 或是以下的步骤来安装 HyperKit 的驱动程序(必要): - ```shell script - curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-hyperkit - sudo install -o root -g wheel -m 4755 docker-machine-driver-hyperkit /usr/local/bin/ - ``` -3. 更新 minikube 配置,使其默认虚拟机管理程序为HyperKit:`minikube config set vm-driver hyperkit`。 -4. 修改 docker desktop 以使用 Kubernetes 的 minikube:
- ![Kubernetes in Docker Desktop: minikube setting](./../assets/docker-dektop-minikube.png) - -### 部署和访问集群 -安装完成后,你可以开始启动一个新的集群。 -1. 启动 minikube 集群: `minikube start --kubernetes-version v1.24.7` -2. 启动 minikube 仪表板: `minikube dashboard &` - -### 开发环境对构建的影响 -在创建映像之前,确保你的 minikube 运行在正确的环境中。 -如果没有设定 minikube 环境,就会在部署调度器的时候找不到docker映像。 -1. 确保 minikube 已启动。 -2. 在你要运行构建的终端中,执行: `eval $(minikube docker-env)` -3. 在 yunikorn-k8shim 的根目录创建映像: `make image` -4. 按照正常指令部署调度器。 - -## 使用 Kind 的设置本地的 Kubernetes 集群 - -Kind(Kubernetes in Docker)是一个轻量级的工具,主要用来运行轻量级Kubernetes环境。 用kind测试不同的Kubernetes版本是非常容易的,只需选择你想要的映像。 - -### 安装 - -如果你已经安装过go,可以直接运行`go install sigs.k8s.io/kind@latest`。 - -可在[Kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)的文件上找到其他方法。 - -Kubernetes 1.25 或更高版本需要 Kind 版本 0.15。Kind 的更高版本添加了 Kubernetes 1.26、1.27 和 1.28。检查种类发行说明以了解支持的特定 Kubernetes 版本 - -### 使用 Kind - -若要要测试新版本的Kubernetes,你可以从kind的repo中拉出一个相应的映像。 - -创建版本为 v1.24.7 的 Kubernetes 集群: `kind create cluster --name test --image kindest/node:v1.24.7` - -删除 kind 集群: `kind delete cluster --name test` - -### 载入你的映像 - -为了使用本地镜像,你必须将你的映像加载到kind的注册表(registry)中。 如果你运行`make image`,你可以使用下面的命令来加载你的kind映像。 以下假设为AMD64架构。 - -下面是调度器、网页UI和存取控制器的例子: - -调度器: -`kind load docker-image apache/yunikorn:scheduler-amd64-latest` - -网页UI: -`kind load docker-image apache/yunikorn:web-amd64-latest` - -存取控制器: -`kind load docker-image apache/yunikorn:admission-amd64-latest` - -## 在本地调试代码 - -注意,这个指令要求你在 GoLand IDE 进行开发。 - -在GoLand中,进入yunikorn-k8shim项目。然后点击 "Run" -> "Debug..." -> "Edit Configuration..." 获取弹出的配置窗口。 -注意,如果第一次没有 "Go Build "选项,你需要点击 "+"来创建一个新的配置文件。 - -![Debug Configuration](./../assets/goland_debug.jpg) - -强调的字段是你需要添加的配置。包括以下: - -- Run Kind: package -- Package path: 指向 `pkg/shim` 的路径 -- Working directory: 指向`conf`目录的路径,这是程序加载配置文件的地方。 -- Program arguments: 指定运行程序的参数,如 `-kubeConfig=/path/to/.kube/config -interval=1s -clusterId=mycluster -clusterVersion=0.1 -name=yunikorn -policyGroup=queues -logEncoding=console -logLevel=-1`. -注意,你需要把`/path/to/.kube/config`替换为kubeconfig文件的本地路径。如果你想改变或添加更多的选项,你可以运行`_output/bin/k8s-yunikorn-scheduler -h`来了解。 - -修改完成后,点击 "Apply",然后点击 "Debug"。你将需要设置适当的断点,以便调试程序。 - -## 存取远端的 Kubernetes 集群 - -这个设置的前提是你已经安装了一个远程Kubernetes集群。 -关于如何访问多个集群并将其整合,请参考Kubernetes的[访问多个集群](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)文档。 - -或者按照这些简化的步骤: -1. 从远程集群获取Kubernetes的`config`文件,将其复制到本地机器上,并给它一个唯一的名字,即`config-remote`。 -2. 更新 `KUBECONFIG` 环境变量(如果已设置)。 - ```shell script - export KUBECONFIG_SAVED=$KUBECONFIG - ``` -3. 将新文件添加到环境变量中。 - ```shell script - export KUBECONFIG=$KUBECONFIG:config-remote - ``` -4. 运行`kubectl config view`命令,检查是否可以访问这两个配置。 -5. 透过以下命令切换配置 `kubectl config use-context my-remote-cluster` -6. 确认是否切换到了远程集群的配置: - ```text - kubectl config get-contexts - CURRENT NAME CLUSTER AUTHINFO NAMESPACE - docker-for-desktop docker-for-desktop-cluster docker-for-desktop - * my-remote-cluster kubernetes kubernetes-admin - ``` - -更多的文件可以在[这里](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)找到。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/openshift_development.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/openshift_development.md deleted file mode 100644 index dad1275a1ea..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/openshift_development.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -id: openshift_development -title: Development in CodeReady Containers ---- - - - -YuniKorn 针对 OpenShift 进行了测试,开发人员可以设置本地环境来针对 OpenShift 测试补丁。 -我们推荐本地环境使用 CodeReady 容器。 - -## 设置正在运行的 CRC 集群 - -1. 下载 CodeReady 容器二进制文件 - - 从下拉列表中选择您的操作系统,然后单击“下载”(在 Mac 上,您将下载 crc-macos-amd64.tar.xz;在 Linux 上,crc-linux-amd64.tar.xz)。 - 系统会要求您使用 Red Hat 登录名进行连接。 如果您没有,只需单击“立即创建”。 您 *不* 需要 Red Hat 订阅。 - - 登录后,下载 CodeReady Containers 二进制文件和 pull secret。 - -1. 解压缩 tar 文件。 - - ```bash - tar -xvzf crc-macos-amd64.tar.xz - ``` - -1. 将 crc 二进制文件移到您的路径下。 像 - - ```bash - sudo cp `pwd`/crc-macos-$CRCVERSION-amd64/crc /usr/local/bin - ``` - -1. 根据您的硬件能力配置 CRC 。 - - ```bash - crc config set memory 16000 - crc config set cpus 12 - crc setup - ``` -1. 启动 CRC 并打开控制台。 - - ```bash - crc start --pull-secret-file pull-secret.txt - crc console - ``` - -## 测试补丁 - -以下步骤假设您的笔记本电脑中有一个正在运行的 CRC 集群。 -:::note -这些步骤未针对远程 CRC 集群进行测试。 -::: - -1. 通过 `oc` 命令访问您的环境。 - - 在 shell 中输入 `crc oc-env` 命令。 - ```bash - $ crc oc-env - export PATH="/Users//.crc/bin/oc:$PATH" - # Run this command to configure your shell: - # eval $(crc oc-env) - ``` - 所以你需要输入这个来访问 `oc` 命令: - ``` - eval $(crc oc-env) - ``` - -1. 登录到 “oc” 。 CRC 启动后,它会显示类似的消息: - - ``` - To access the cluster, first set up your environment by following 'crc oc-env' instructions. - Then you can access it by running 'oc login -u developer -p developer https://api.crc.testing:6443'. - To login as an admin, run 'oc login -u kubeadmin -p duduw-yPT9Z-hsUpq-f3pre https://api.crc.testing:6443'. - To access the cluster, first set up your environment by following 'crc oc-env' instructions. - ``` - - 使用 `oc login -u kubeadmin ...` 命令。 - -1. 通过输入以下命令获取本地 OpenShift 集群的内部私有 Docker 存储库的 URL。 - - ```bash - $ oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}' - default-route-openshift-image-registry.apps-crc.testing - ``` - - 默认情况下,它应该是 “default-route-openshift-image-registry.apps-crc.testing” 。 如果显示的 URL 不同,请更改上述步骤。 - -1. 准备 Docker 镜像。 - - 您可以在底部的 *使用自定义镜像* 部分阅读更多相关信息。 - -1. 准备 helm chart. - - 如果您想使用自定义 Docker 镜像,请替换 helm chart 的 “values.yaml” 配置文件中的镜像。 - - :::note - 如果您直接将 Docker 镜像手动推送到 `default-route-openshift-image-registry.apps-crc.testing` docker registry ,您需要有有效的证书才能访问它。 - 在 OpenShift 上有更容易使用的服务:`image-registry.openshift-image-registry.svc`。 - ::: - - 例如,如果你想覆盖所有 Docker 镜像,你应该使用以下配置: - ```yaml - image: - repository: image-registry.openshift-image-registry.svc:5000/yunikorn/yunikorn - tag: scheduler-latest - pullPolicy: Always - - admission_controller_image: - repository: image-registry.openshift-image-registry.svc:5000/yunikorn/yunikorn - tag: admission-latest - pullPolicy: Always - - web_image: - repository: image-registry.openshift-image-registry.svc:5000/yunikorn/yunikorn-web - tag: latest - pullPolicy: Always - ``` - - 您可以在 yunikorn-release 存储库的 helm chart 目录中找到它。 - -1. 安装 helm charts. - - ```bash - helm install yunikorn . -n yunikorn - ``` - -## 使用自定义镜像 - -### Podman - -1. 使用以下命令登录 Podman。 - - ```bash - podman login --tls-verify=false -u kubeadmin -p $(oc whoami -t) default-route-openshift-image-registry.apps-crc.testing - ``` - -1. 在存储库中构建镜像,例如 在 shim 中使用通用的 “make image” 命令。 - -1. 验证镜像是否存在于存储库中。 - - ```bash - podman images - REPOSITORY TAG IMAGE ID CREATED SIZE - localhost/apache/yunikorn admission-latest 19eb41241d64 About a minute ago 53.5 MB - localhost/apache/yunikorn scheduler-latest e60e09b424d9 About a minute ago 543 MB - ``` - -## 直接推送 OS 镜像注册 - -1. 创建您要替换的镜像。 - - 您可以在本地构建新镜像或使用官方镜像(也可以混合使用)。 - * 对于 -shim 和 -web 镜像检查存储库(可选择进行更改)并输入以下命令: - ```bash - make clean image REGISTRY=default-route-openshift-image-registry.apps-crc.testing//: - ``` - :::note - 在 OpenShift 中,一个计划相当于一个 Kubernetes 命名空间。 推荐使用 `yunikorn` 项目/命名空间。 - ::: - - * 可以使用官方镜像,通过 “docker tag” 命令重新标记。 - ```bash - docker tag apache/yunikorn:scheduler-latest default-route-openshift-image-registry.apps-crc.testing/yunikorn/yunikorn:scheduler-latest - ``` - -1. 登录到 Docker 存储库。 - ```bash - docker login -u kubeadmin -p $(oc whoami -t) default-route-openshift-image-registry.apps-crc.testing - ``` - -1. 将 Docker 镜像推送到内部 Docker 存储库 - ``` - docker push default-route-openshift-image-registry.apps-crc.testing/yunikorn/yunikorn:scheduler-latest - ``` \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/translation.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/translation.md deleted file mode 100644 index 2e74494ed86..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/developer_guide/translation.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: translation -title: 翻译 ---- - - - -Yunikorn网站采用Docusaurus管理文档。 -[Docusaurus国际化系统(i18n)](https://docusaurus.io/docs/i18n/tutorial)允许开发人员翻译文档。 -为网站添加新的语言翻译时,开发者应进行如下操作。 - -## 修改docusaurus.config.js以支持新语言 -假设通过**新语言关键字**进行翻译。 -预期的结果会像这个图(右上方的<新语言关键字>為test)。 -![翻译结果](./../assets/translationDemo.png) - -当前的Yunikorn网站包括**en**和**zh-cn**文档。 -如果开发者想添加一个新的带有**新语言关键字**的翻译,如fr, jp。 -则开发者需要修改`docusaurus.config.js`中的`i18n`栏位。 -``` -i18n: { - defaultLocale: 'en', - locales: ['en', 'zh-cn', '<新语言关键字>'], - localeConfigs: { - en: { - label: 'English', - }, - "zh-cn": { - label: '中文', - }, - "<新语言关键字>": { - label: 'test', - } - }, - }, -``` -## 更新local-build.sh中的帮助信息 -将**新语言关键字**添加到`print_usage`函数的语言环境列表中。 -``` -Usage: $(basename "$0") run [locale] | build | clean | help - run build the website, and launch the server in a docker image. - a locale can be specified, currently supported: "en", "zh-cn", "<新语言关键字>" -``` - -## 将最新文件复制到i18n资料夹 -``` -mkdir -p i18n/<新语言关键字>/docusaurus-plugin-content-docs/current -cp -r docs/** i18n/<新语言关键字>/docusaurus-plugin-content-docs/current -mkdir -p i18n/<新语言关键字>/docusaurus-plugin-content-pages -cp -r src/pages/** i18n/<新语言关键字>/docusaurus-plugin-content-pages -mkdir -p i18n/<新语言关键字>/docusaurus-theme-classic -``` - -## 在sidebar.json和footer.json中添加翻译后的信息 -在docusaurus-theme-classic资料夹中创建sidebar.json和footer.json档案。 -例如,添加的footer.json内容如下。 -``` -{ - "link.item.label.Get Involved": { - "message": "参与" - }, - "link.title.Code Repositories": { - "message": "代码库" - }, - "link.item.label.People": { - "message": "人们" - }, - "link.title.Blog": { - "message": "博客" - }, - "link.title.Community": { - "message": "社区" - } -} -``` - - - -## 链接img、assest与styles.module.css -在`i18n/new language keyword/docusaurus-plugin-content-pages`中创建链接文件。 - -``` -# 清理重复文件 -rm -rf img -rm styles.module.css -# 链接 -ln -s ../../../static/img -ln -s ../../../src/pages/styles.module.css -``` - -在`i18n/new language keyword/docusaurus-plugin-content-docs/current`中创建链接文件。 -``` -# 清理重复文件 -rm -rf assests -# 链接 -ln -s ../../../../docs/assets -``` - -## 采用相对路径 -`src/pages/index.js`中有部分图片url采用绝对路径,采用绝对路径会导致png丢失。 -开发人员需要确保`/i18n/new language keyword/docusaurus-plugin-content-pages/index.js`中的图链接有效。 -例如,在`index.js`中有一个`resource-scheduling.png`图像,图像链接是`/img/resource-scheduling.png`。 -``` -/img/resource-scheduling.png -> ./img/resource-scheduling.png -``` -## 测试 -``` -./local-build.sh run <新语言关键字> -``` -![建设网站](./../assets/translationBuilding.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/get_started/core_features.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/get_started/core_features.md deleted file mode 100644 index d6d3c497992..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/get_started/core_features.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: core_features -title: 特征 -keywords: - - 特征 ---- - - - -YuniKorn的主要特点包括: - -## 应用感知调度 - -YuniKorn的关键特性之一就是支持应用感知。在默认的K8s调度程序中,它只能根据Pod进行调度,而不能基于用户、作业或者队列进行更细粒度的调度。 -与之不同的是,YuniKorn可以识别用户、作业或者队列,并在做出调度决策时,考虑更多与它们相关的因素,如资源、排序等。 -这使我们能够对资源配额、资源公平性和优先级进行细粒度控制,这是多租户计算系统最重要的需求。 - -## 层次资源队列 - -层次队列提供了一种有效的机制来管理集群资源。 -队列的层次结构可以在逻辑上映射到组织结构。这为不同租户提供了对资源的细粒度控制。 -YuniKorn UI 提供了一个集中的视图来监视资源队列的使用情况,它可以帮助您了解不同租户是如何使用资源的。 -此外,用户可以利用设置最小/最大队列容量来为每个租户设定其弹性资源配额。 - -## 作业排序和排队 - -YuniKorn将每个资源队列中的队列进行排队,排序策略决定哪个应用程序可以首先获得资源。 -这个策略可以是多种多样的,例如简单的 `FIFO`、`Fair`、`StateAware` 或基于 `Priority` 的策略。 -队列可以维持应用的顺序,调度器根据不同的策略为作业分配相应的资源。这种行为更容易被理解和控制。 - -此外,当配置队列最大容量时,作业和任务可以在资源队列中正确排队。 -如果剩余的容量不够,它们可以排队等待,直到释放一些资源。这就简化了客户端操作。 -而在默认调度程序中,资源由命名空间资源配额限制:如果命名空间没有足够的配额,Pod就不能被创建。这是由配额许可控制器强制执行的。 -客户端需要更复杂的逻辑来处理此类场景,例如按条件重试。 - -## 资源公平性 - -在多租户环境中,许多用户共享集群资源。 -为了避免租户争夺资源或者可能的资源不足,需要做到更细粒度的公平性需求,以此来实现跨用户以及跨团队/组织的公平性。 -考虑到权重或优先级,一些更重要的应用可以获得超过其配额的更多的需求资源。 -这往往与资源预算有关,更细粒度的公平模式可以进一步提高资源控制。 - -## 资源预留 - -YuniKorn会自动为未完成的请求进行资源预留。 -如果Pod无法分配,YuniKorn将尝试把它预留在一个满足条件的节点上,并在这个节点上暂时分配该 pod(在尝试其他节点之前)。 -这种机制可以避免这个 Pod 需要的资源被后来提交的更小的、更不挑剔的 Pod 所挤占。 -此功能在批处理工作负载场景中非常重要,因为当对集群提交大量异构 Pod 时,很有可能一些 Pod 会处于“饥饿”状态,即使它们提交得更早。 - -## 吞吐量 - -吞吐量是衡量调度器性能的关键标准。这对于一个大规模的分布式系统来说是至关重要的。 -如果吞吐量不好,应用程序可能会浪费时间等待调度,并进一步影响服务的 SLA(服务级别协议)。 -集群越大,对吞吐量的要求也越高。[基于Kube标记的运行评估](performance/evaluate_perf_function_with_kubemark.md) 章节显示了一些性能数据。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/get_started/get_started.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/get_started/get_started.md deleted file mode 100644 index fcf009f0f5e..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/get_started/get_started.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: user_guide -title: 开始 -slug: / ---- - - - -在阅读本指南之前,我们假设您有一个Kubernetes集群或本地 Kubernetes 开发环境,例如 MiniKube。 -还假定 `kubectl` 在您的环境路径内,并且配置正确。 -遵循此 [指南](developer_guide/env_setup.md) 来讲述如何使用 docker-desktop 设置本地Kubernetes集群。 - -## 安装 - -最简单的方法是使用我们的 Helm Chart 在现有的Kubernetes集群上部署YuniKorn。 -我们建议使用 Helm 3 或更高版本。 - -```shell script -helm repo add yunikorn https://apache.github.io/yunikorn-release -helm repo update -kubectl create namespace yunikorn -helm install yunikorn yunikorn/yunikorn --namespace yunikorn -``` - -默认情况下,Helm Chart 将在集群中安装调度器、web服务器和 admission-controller。 -`admission-controller` 一旦安装,它将把所有集群流量路由到YuniKorn。 -这意味着资源调度会委托给YuniKorn。在Helm安装过程中,可以通过将 `embedAdmissionController` 标志设置为 `false` 来禁用它。 -通过将Helm的 `enableSchedulerPlugin` 标志设置为 `true`,YuniKorn调度器也可以以Kubernetes的调度器插件的方式进行部署。 -这种方式将会部署一个包含与默认调度器一起编译的YuniKorn备用Docker镜像。 -这种新模式借助默认的Kubernetes调度器提供了更好的兼容性,并且适合与将所有调度委托给YuniKorn的 admission-controller 协同使用。 -因为这个模式还是很新的,所以默认没有开启。 - -如果您不确定应该使用哪种部署模式,请参阅我们 [并列比较](user_guide/deployment_modes) 章节的内容。 - -如果你不想使用 Helm Chart,您可以找到我们的细节教程 [点击这里](developer_guide/deployment.md) 。 - -## 卸载 - -运行如下的命令卸载 YuniKorn: - -```shell script -helm uninstall yunikorn --namespace yunikorn -``` - -## 访问 Web UI - -当部署调度程序时,Web UI 也会部署在容器中。 -我们可以通过以下方式在标准端口上打开 Web 界面的端口转发: - -```shell script -kubectl port-forward svc/yunikorn-service 9889:9889 -n yunikorn -``` - -`9889` 是 Web UI 的默认端口。 -完成此操作后,web UI将在以下地址可用: http://localhost:9889 。 - -![UI 截图](./../assets/yk-ui-screenshots.gif) - -YuniKorn UI 提供了集群资源容量、利用率和所有应用信息的集中视图。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/evaluate_perf_function_with_kubemark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/evaluate_perf_function_with_kubemark.md deleted file mode 100644 index 44f4c67ebda..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/evaluate_perf_function_with_kubemark.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: evaluate_perf_function_with_kubemark -title: 使用 Kubemark 评估 YuniKorn 的性能 -keywords: - - 性能 - - 吞吐量 ---- - - - -YuniKorn 社区关注调度程序的性能,并继续在发布时对其进行优化。 社区已经开发了一些工具来反复测试和调整性能。 - -## 环境设置 - -我们利用[Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster)评估调度器的性能。 Kubemark是一个模拟大规模集群的测试工具。 它创建空节点,运行空kubelet以假装原始kubelet行为。 这些空节点上的调度pod不会真正执行。它能够创建一个满足我们实验要求的大集群,揭示yunikorn调度器的性能。 请参阅有关如何设置环境的[详细步骤](performance/performance_tutorial.md)。 - -## 调度程序吞吐量 - -我们在模拟的大规模环境中设计了一些简单的基准测试场景,以评估调度器的性能。 我们的工具测量[吞吐量](https://en.wikipedia.org/wiki/Throughput)并使用这些关键指标来评估性能。 简而言之,调度程序吞吐量是处理pod从在集群上发现它们到将它们分配给节点的速率。 - -在本实验中,我们使用 [Kubemark](https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/devel/kubemark-guide.md#starting-a-kubemark-cluster) 设置了一个模拟的2000/4000节点集群。然后我们启动10个[部署](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/),每个部署分别设置5000个副本。 这模拟了大规模工作负载同时提交到K8s集群。 我们的工具会定期监控和检查pod状态,随着时间的推移,根据 `podSpec.StartTime` 计算启动的pod数量。 作为对比,我们将相同的实验应用到相同环境中的默认调度程序。 我们看到了YuniKorn相对于默认调度程序的性能优势,如下图所示: - -![Scheduler Throughput](./../assets/yunirkonVSdefault.png) -

图 1. Yunikorn 和默认调度器吞吐量

- -图表记录了集群上所有 Pod 运行所花费的时间: - -| 节点数 | yunikorn | k8s 默认调度器 | 差异 | -|------------------ |:--------------: |:---------------------: |:-----: | -| 2000(节点) | 204(pods/秒) | 49(pods/秒) | 416% | -| 4000(节点) | 115(pods/秒) | 48(pods/秒) | 240% | - -为了使结果标准化,我们已经运行了几轮测试。 如上所示,与默认调度程序相比,YuniKorn实现了`2 倍`~`4 倍`的性能提升。 - -:::note - -与其他性能测试一样,结果因底层硬件而异,例如服务器CPU/内存、网络带宽、I/O速度等。为了获得适用于您的环境的准确结果,我们鼓励您运行这些测试在靠近生产环境的集群上。 - -::: - -## 性能分析 - -我们从实验中得到的结果是有希望的。 我们通过观察更多的YuniKorn内部指标进一步深入分析性能,我们能够找到影响性能的几个关键区域。 - -### K8s 限制 - -我们发现整体性能实际上受到了K8s主服务的限制,例如api-server、controller-manager和etcd,在我们所有的实验中都没有达到YuniKorn的限制。 如果您查看内部调度指标,您可以看到: - -![Allocation latency](./../assets/allocation_4k.png) -

图 2. 4k 节点中的 Yunikorn 指标

- -图2是Prometheus的截图,它记录了YuniKorn中的[内部指标](performance/metrics.md) `containerAllocation`。 它们是调度程序分配的 pod 数量,但不一定绑定到节点。 完成调度50k pod大约需要122秒,即410 pod/秒。 实际吞吐量下降到115个 Pod/秒,额外的时间用于绑定不同节点上的Pod。 如果K8s方面能赶上来,我们会看到更好的结果。 实际上,当我们在大规模集群上调整性能时,我们要做的第一件事就是调整API-server、控制器管理器中的一些参数,以提高吞吐量。 在[性能教程文档](performance/performance_tutorial.md)中查看更多信息。 - -### 节点排序 - -当集群大小增加时,我们看到YuniKorn的性能明显下降。 这是因为在YuniKorn中,我们对集群节点进行了完整排序,以便为给定的pod找到 **“best-fit”** 节点。 这种策略使Pod分布更加优化,基于所使用的 [节点排序策略](./../user_guide/sorting_policies#node-sorting)。 但是,对节点进行排序很昂贵,在调度周期中这样做会产生很多开销。 为了克服这个问题,我们在 [YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807) 中改进了我们的节点排序机制,其背后的想法是使用 [B-Tree ](https://en.wikipedia.org/wiki/B-tree)来存储所有节点并在必要时应用增量更新。 这显着改善了延迟,根据我们的基准测试,这在500、1000、2000 和 5000个节点的集群上分别提高了 35 倍、42 倍、51 倍、74 倍。 - -### 每个节点的前提条件检查 - -在每个调度周期中,另一个耗时的部分是节点的“前提条件检查”。 在这个阶段,YuniKorn评估所有K8s标准断言(Predicates),例如节点选择器、pod亲和性/反亲和性等,以确定pod是否适合节点。 这些评估成本很高。 - -我们做了两个实验来比较启用和禁用断言评估的情况。 请参阅以下结果: - -![Allocation latency](./../assets/predicateComaparation.png) -

图 3. Yunikorn 中的断言效果比较

- -当断言评估被禁用时,吞吐量会提高很多。 我们进一步研究了整个调度周期的延迟分布和断言评估延迟。 并发现: - -![YK predicate latency](./../assets/predicate_4k.png) -

图 4. 断言延迟

- -![YK scheduling with predicate](./../assets/scheduling_with_predicate_4k_.png) -

图 5. 启用断言的调度时间

- -![YK scheduling with no predicate](./../assets/scheduling_no_predicate_4k.png) -

图 6. 不启用断言的调度时间

- -总体而言,YuniKorn 调度周期运行得非常快,每个周期的延迟下降在 **0.001s - 0.01s** 范围内。 并且大部分时间用于断言评估,10倍于调度周期中的其他部分。 - -| | 调度延迟分布(秒) | 断言-评估延迟分布(秒) | -|----------------------- |:---------------------: |:---------------------: | -| 启用断言 | 0.01 - 0.1 | 0.01-0.1 | -| 不启用断言 | 0.001 - 0.01 | 无 | - -## 为什么 YuniKorn 更快? - -默认调度器被创建为面向服务的调度器; 与YuniKorn相比,它在吞吐量方面的敏感性较低。 YuniKorn社区非常努力地保持出色的性能并不断改进。 YuniKorn可以比默认调度器运行得更快的原因是: - -* 短调度周期 - -YuniKorn 保持调度周期短而高效。 YuniKorn 使用所有异步通信协议来确保所有关键路径都是非阻塞调用。 大多数地方只是在进行内存计算,这可能非常高效。 默认调度器利用 [调度框架](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/),它为扩展调度器提供了很大的灵活性,但是,权衡是性能。 调度周期变成了一条很长的链,因为它需要访问所有这些插件。 - -* 异步事件处理 - -YuniKorn利用异步事件处理框架来处理内部状态。 这使得核心调度周期可以快速运行而不会被任何昂贵的调用阻塞。 例如,默认调度程序需要将状态更新、事件写入pod对象,这是在调度周期内完成的。 这涉及将数据持久化到etcd,这可能很慢。 YuniKorn将所有此类事件缓存在一个队列中,并以异步方式写回pod。 - -* 更快的节点排序 - -[YUNIKORN-807](https://issues.apache.org/jira/browse/YUNIKORN-807)之后,YuniKorn进行了高效的增量节点排序。 这是建立在所谓的基于“资源权重”的节点评分机制之上的,它也可以通过插件进行扩展。 所有这些一起减少了计算节点分数时的开销。 相比之下,默认调度器提供了一些计算节点分数的扩展点,例如`PreScore`、`Score`和`NormalizeScore`。 这些计算量很大,并且在每个调度周期中都会调用它们。 请参阅[代码行](https://github.com/kubernetes/kubernetes/blob/481459d12dc82ab88e413886e2130c2a5e4a8ec4/pkg/scheduler/framework/runtime/framework.go#L857)中的详细信息。 - -## 概括 - -在测试过程中,我们发现YuniKorn的性能非常好,尤其是与默认调度程序相比。 我们已经确定了YuniKorn中可以继续提高性能的主要因素,并解释了为什么YuniKorn的性能优于默认调度程序。 我们还意识到将Kubernetes扩展到数千个节点时的局限性,可以通过使用其他技术(例如联合)来缓解这些局限性。 因此,YuniKorn是一个高效、高吞吐量的调度程序,非常适合在Kubernetes上运行批处理/混合工作负载。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/metrics.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/metrics.md deleted file mode 100644 index 7d6fa73e5b8..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/metrics.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: metrics -title: 调度程序指标 -keywords: - - 指标 ---- - - - -YuniKorn利用[Prometheus](https://prometheus.io/) 记录指标。 度量系统不断跟踪调度程序的关键执行路径,以揭示潜在的性能瓶颈。 目前,这些指标分为三类: - -- 调度器:调度器的通用指标,例如分配延迟、应用程序数量等。 -- 队列:每个队列都有自己的指标子系统,跟踪队列状态。 -- 事件:记录YuniKorn中事件的各种变化。 - -所有指标都在`yunikorn`命名空间中声明。 -### 调度程序指标 - -| 指标名称 | 指标类型 | 描述 | -| --------------------- | ------------ | ------------ | -| containerAllocation | Counter | 尝试分配容器的总次数。 尝试状态包括`allocated`, `rejected`, `error`, `released`。 该指标只会增加。 | -| applicationSubmission | Counter | 提交申请的总数。 尝试的状态包括 `accepted`和`rejected`。 该指标只会增加。 | -| applicationStatus | Gauge | 申请状态总数。 应用程序的状态包括`running`和`completed`。 | -| totalNodeActive | Gauge | 活动节点总数。 | -| totalNodeFailed | Gauge | 失败节点的总数。 | -| nodeResourceUsage | Gauge | 节点的总资源使用情况,按资源名称。 | -| schedulingLatency | Histogram | 主调度例程的延迟,以秒为单位。 | -| nodeSortingLatency | Histogram | 所有节点排序的延迟,以秒为单位。 | -| appSortingLatency | Histogram | 所有应用程序排序的延迟,以秒为单位。 | -| queueSortingLatency | Histogram | 所有队列排序的延迟,以秒为单位。 | -| tryNodeLatency | Histogram | 节点条件检查容器分配的延迟,例如放置约束,以秒为单位。 | - -### 队列指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------- | ------------- | ----------- | -| appMetrics | Counter | 应用程序指标,记录申请总数。 应用程序的状态包括`accepted`、`rejected`和`Completed`。 | -| usedResourceMetrics | Gauge | 排队使用的资源。 | -| pendingResourceMetrics | Gauge | 排队等待的资源。 | -| availableResourceMetrics | Gauge | 与队列等相关的已用资源指标。 | - -### 事件指标 - -| 指标名称 | 指标类型 | 描述 | -| ------------------------ | ------------ | ----------- | -| totalEventsCreated | Gauge | 创建的事件总数。 | -| totalEventsChanneled | Gauge | 引导的事件总数。 | -| totalEventsNotChanneled | Gauge | 引导的事件总数。 | -| totalEventsProcessed | Gauge | 处理的事件总数。 | -| totalEventsStored | Gauge | 存储的事件总数。 | -| totalEventsNotStored | Gauge | 未存储的事件总数。 | -| totalEventsCollected | Gauge | 收集的事件总数。 | - -## 访问指标 - -YuniKorn指标通过Prometheus客户端库收集,并通过调度程序RESTful服务公开。 -启动后,可以通过端点http://localhost:9080/ws/v1/metrics访问它们。 - -## Prometheus 的聚合指标 - -设置 Prometheus 服务器以定期获取 YuniKorn 指标很简单。 按着这些次序: - -- 设置Prometheus(从[Prometheus 文档](https://prometheus.io/docs/prometheus/latest/installation/)了解更多信息) - -- 配置Prometheus规则:示例配置 - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] -``` - -- 启动 Prometheus - -```shell script -docker pull prom/prometheus:latest -docker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus -``` - -如果您在Mac OS上的本地docker容器中运行Prometheus,请使用`docker.for.mac.host.internal`而不是`localhost`。 启动后,打开Prometheus网页界面:http://localhost:9090/graph。 您将看到来自YuniKorn调度程序的所有可用指标。 - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/performance_tutorial.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/performance_tutorial.md deleted file mode 100644 index 8180fa0716d..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/performance_tutorial.md +++ /dev/null @@ -1,451 +0,0 @@ ---- -id: performance_tutorial -title: 基准测试教程 -keywords: - - 性能 - - 教程 ---- - - - -## 概述 - -YuniKorn社区不断优化调度器的性能,确保YuniKorn满足大规模批处理工作负载的性能要求。 因此,社区为性能基准测试构建了一些有用的工具,可以跨版本重用。 本文档介绍了所有这些工具和运行它们的步骤。 - -## 硬件 - -请注意,性能结果因底层硬件而异。 文档中发布的所有结果只能作为参考。 我们鼓励每个人在自己的环境中运行类似的测试,以便根据您自己的硬件获得结果。 本文档仅用于演示目的。 - -本次测试中使用的服务器列表是(非常感谢[国立台中教育大学](http://www.ntcu.edu.tw/newweb/index.htm), [Kuan-Chou Lai](http://www.ntcu.edu.tw/kclai/) 为运行测试提供这些服务器): - -| 机型 | CPU | 内存 | 下载/上传(Mbps) | -| --------------------- | --- | ------ | --------------------- | -| HP | 16 | 36G | 525.74/509.86 | -| HP | 16 | 30G | 564.84/461.82 | -| HP | 16 | 30G | 431.06/511.69 | -| HP | 24 | 32G | 577.31/576.21 | -| IBM blade H22 | 16 | 38G | 432.11/4.15 | -| IBM blade H22 | 16 | 36G | 714.84/4.14 | -| IBM blade H22 | 16 | 42G | 458.38/4.13 | -| IBM blade H22 | 16 | 42G | 445.42/4.13 | -| IBM blade H22 | 16 | 32G | 400.59/4.13 | -| IBM blade H22 | 16 | 12G | 499.87/4.13 | -| IBM blade H23 | 8 | 32G | 468.51/4.14 | -| WS660T | 8 | 16G | 87.73/86.30 | -| ASUSPRO D640MB_M640SA | 4 | 8G | 92.43/93.77 | -| PRO E500 G6_WS720T | 16 | 8G | 90/87.18 | -| WS E500 G6_WS720T | 8 | 40G | 92.61/89.78 | -| E500 G5 | 8 | 8G | 91.34/85.84 | -| WS E500 G5_WS690T | 12 | 16G | 92.2/93.76 | -| WS E500 G5_WS690T | 8 | 32G | 91/89.41 | -| WS E900 G4_SW980T | 80 | 512G | 89.24/87.97 | - -每个服务器都需要执行以下步骤,否则由于用户/进程/打开文件的数量有限,大规模测试可能会失败。 - -### 1. 设置/etc/sysctl.conf -``` -kernel.pid_max=400000 -fs.inotify.max_user_instances=50000 -fs.inotify.max_user_watches=52094 -``` -### 2. 设置/etc/security/limits.conf - -``` -* soft nproc 4000000 -* hard nproc 4000000 -root soft nproc 4000000 -root hard nproc 4000000 -* soft nofile 50000 -* hard nofile 50000 -root soft nofile 50000 -root hard nofile 50000 -``` ---- - -## 部署工作流 - -在进入细节之前,这里是我们测试中使用的一般步骤: - -- [步骤 1](#Kubernetes): 正确配置Kubernetes API服务器和控制器管理器,然后添加工作节点。 -- [步骤 2](#Setup-Kubemark): 部署空pod,将模拟工作节点,命名空节点。 在所有空节点都处于就绪状态后,我们需要封锁(cordon)所有本地节点,这些本地节点是集群中的物理存在,而不是模拟节点,以避免我们将测试工作负载 pod 分配给本地节点。 -- [步骤 3](#Deploy-YuniKorn): 在主节点上使用Helm chart部署YuniKorn,并将 Deployment 缩减为 0 副本,并在`prometheus.yml`中 [修改端口](#Setup-Prometheus) 以匹配服务的端口。 -- [步骤 4](#Run-tests): 部署50k Nginx pod进行测试,API服务器将创建它们。 但是由于YuniKorn调度程序Deployment已经被缩减到0个副本,所有的Nginx pod都将停留在等待状态。 -- [步骤 5](../user_guide/troubleshooting.md#restart-the-scheduler): 将YuniKorn部署扩展回1个副本,并封锁主节点以避免YuniKorn 在那里分配Nginx pod。 在这一步中,YuniKorn将开始收集指标。 -- [步骤 6](#Collect-and-Observe-YuniKorn-metrics): 观察Prometheus UI中公开的指标。 ---- - -## 设置 Kubemark - -[Kubemark](https://github.com/kubernetes/kubernetes/tree/master/test/kubemark)是一个性能测试工具,允许用户在模拟集群上运行实验。 主要用例是可扩展性测试。 基本思想是在一个物理节点上运行数十或数百个假kubelet节点,以模拟大规模集群。 在我们的测试中,我们利用 Kubemark 在少于20个物理节点上模拟多达4K节点的集群。 - -### 1. 构建镜像 - -##### 克隆kubernetes仓库,并构建kubemark二进制文件 - -``` -git clone https://github.com/kubernetes/kubernetes.git -``` -``` -cd kubernetes -``` -``` -KUBE_BUILD_PLATFORMS=linux/amd64 make kubemark GOFLAGS=-v GOGCFLAGS="-N -l" -``` - -##### 将kubemark二进制文件复制到镜像文件夹并构建kubemark docker镜像 - -``` -cp _output/bin/kubemark cluster/images/kubemark -``` -``` -IMAGE_TAG=v1.XX.X make build -``` -完成此步骤后,您可以获得可以模拟集群节点的kubemark镜像。 您可以将其上传到Docker-Hub或仅在本地部署。 - -### 2. 安装Kubermark - -##### 创建kubemark命名空间 - -``` -kubectl create ns kubemark -``` - -##### 创建configmap - -``` -kubectl create configmap node-configmap -n kubemark --from-literal=content.type="test-cluster" -``` - -##### 创建secret - -``` -kubectl create secret generic kubeconfig --type=Opaque --namespace=kubemark --from-file=kubelet.kubeconfig={kubeconfig_file_path} --from-file=kubeproxy.kubeconfig={kubeconfig_file_path} -``` -### 3. 标签节点 - -我们需要给所有的原生节点打上标签,否则调度器可能会将空pod分配给其他模拟的空节点。 我们可以利用yaml中的节点选择器将空pod分配给本地节点。 - -``` -kubectl label node {node name} tag=tagName -``` - -### 4. 部署Kubemark - -hollow-node.yaml如下所示,我们可以配置一些参数。 - -``` -apiVersion: v1 -kind: ReplicationController -metadata: - name: hollow-node - namespace: kubemark -spec: - replicas: 2000 # 要模拟的节点数 - selector: - name: hollow-node - template: - metadata: - labels: - name: hollow-node - spec: - nodeSelector: # 利用标签分配给本地节点 - tag: tagName - initContainers: - - name: init-inotify-limit - image: docker.io/busybox:latest - imagePullPolicy: IfNotPresent - command: ['sysctl', '-w', 'fs.inotify.max_user_instances=200'] # 设置为与实际节点中的max_user_instance相同 - securityContext: - privileged: true - volumes: - - name: kubeconfig-volume - secret: - secretName: kubeconfig - - name: logs-volume - hostPath: - path: /var/log - containers: - - name: hollow-kubelet - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 4194 - - containerPort: 10250 - - containerPort: 10255 - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=kubelet - - --name=$(NODE_NAME) - - --kubeconfig=/kubeconfig/kubelet.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: - requests: # 空pod的资源,可以修改。 - cpu: 20m - memory: 50M - securityContext: - privileged: true - - name: hollow-proxy - image: 0yukali0/kubemark:1.20.10 # 您构建的kubemark映像 - imagePullPolicy: IfNotPresent - env: - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /kubemark - args: - - --morph=proxy - - --name=$(NODE_NAME) - - --use-real-proxier=false - - --kubeconfig=/kubeconfig/kubeproxy.kubeconfig - - --alsologtostderr - - --v=2 - volumeMounts: - - name: kubeconfig-volume - mountPath: /kubeconfig - readOnly: true - - name: logs-volume - mountPath: /var/log - resources: # 空pod的资源,可以修改。 - requests: - cpu: 20m - memory: 50M - tolerations: - - effect: NoExecute - key: node.kubernetes.io/unreachable - operator: Exists - - effect: NoExecute - key: node.kubernetes.io/not-ready - operator: Exists -``` - -完成编辑后,将其应用于集群: - -``` -kubectl apply -f hollow-node.yaml -``` - ---- - -## 部署 YuniKorn - -#### 使用helm安装YuniKorn - -我们可以用 Helm 安装 YuniKorn,请参考这个[文档](https://yunikorn.apache.org/docs/#install)。 我们需要根据默认配置调整一些参数。 我们建议克隆[发布仓库](https://github.com/apache/yunikorn-release)并修改`value.yaml`中的参数。 - -``` -git clone https://github.com/apache/yunikorn-release.git -cd helm-charts/yunikorn -``` - -#### 配置 - -`value.yaml`中的修改是: - -- 增加调度程序 pod 的内存/cpu 资源 -- 禁用 admission controller -- 将应用排序策略设置为 FAIR - -请参阅以下更改: - -``` -resources: - requests: - cpu: 14 - memory: 16Gi - limits: - cpu: 14 - memory: 16Gi -``` -``` -embedAdmissionController: false -``` -``` -configuration: | - partitions: - - - name: default - queues: - - name: root - submitacl: '*' - queues: - - - name: sandbox - properties: - application.sort.policy: fair -``` - -#### 使用本地版本库安装YuniKorn - -``` -Helm install yunikorn . --namespace yunikorn -``` - ---- - -## 设置Prometheus - -YuniKorn通过Prometheus公开其调度指标。 因此,我们需要设置一个Prometheus服务器来收集这些指标。 - -### 1. 下载Prometheus版本 - -``` -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` -``` -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. 配置prometheus.yml - -``` -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['docker.for.mac.host.internal:9080'] - # 9080为内部端口,需要端口转发或修改9080为服务端口 -``` - -### 3. 启动Prometheus -``` -./prometheus --config.file=prometheus.yml -``` - ---- -## 运行测试 - -设置环境后,您就可以运行工作负载并收集结果了。 YuniKorn社区有一些有用的工具来运行工作负载和收集指标,更多详细信息将在此处发布。 - ---- - -## 收集和观察YuniKorn指标 - -Prometheus 启动后,可以轻松收集 YuniKorn 指标。 这是 YuniKorn 指标的[文档](metrics.md)。 YuniKorn 跟踪一些关键调度指标,这些指标衡量一些关键调度路径的延迟。 这些指标包括: - - - **scheduling_latency_seconds:** 主调度例程的延迟,以秒为单位。 - - **app_sorting_latency_seconds**: 所有应用程序排序的延迟,以秒为单位。 - - **node_sorting_latency_seconds**: 所有节点排序的延迟,以秒为单位。 - - **queue_sorting_latency_seconds**: 所有队列排序的延迟,以秒为单位。 - - **container_allocation_attempt_total**: 尝试分配容器的总次数。 尝试状态包括 `allocated`、`rejected`、`error`、`released`。 该指标仅增加。 - -您可以在Prometheus UI上轻松选择和生成图形,例如: - -![Prometheus Metrics List](./../assets/prometheus.png) - - ---- - -## 性能调优 - -### Kubernetes - -默认的 K8s 设置限制了并发请求,这限制了集群的整体吞吐量。 在本节中,我们介绍了一些需要调整的参数,以提高集群的整体吞吐量。 - -#### kubeadm - -设置pod网络掩码 - -``` -kubeadm init --pod-network-cidr=10.244.0.0/8 -``` - -#### CNI - -修改CNI掩码和资源。 - -``` - net-conf.json: | - { - "Network": "10.244.0.0/8", - "Backend": { - "Type": "vxlan" - } - } -``` -``` - resources: - requests: - cpu: "100m" - memory: "200Mi" - limits: - cpu: "100m" - memory: "200Mi" -``` - - -#### Api-Server - -在 Kubernetes API 服务器中,我们需要修改两个参数:`max-mutating-requests-inflight`和`max-requests-inflight`。 这两个参数代表API请求带宽。 因为我们会产生大量的Pod请求,所以我们需要增加这两个参数。修改`/etc/kubernetes/manifest/kube-apiserver.yaml`: - -``` ---max-mutating-requests-inflight=3000 ---max-requests-inflight=3000 -``` - -#### Controller-Manager - -在Kubernetes控制器管理器中,我们需要增加三个参数的值:`node-cidr-mask-size`、`kube-api-burst` `kube-api-qps`. `kube-api-burst`和`kube-api-qps`控制服务器端请求带宽。`node-cidr-mask-size`表示节点 CIDR。 为了扩展到数千个节点,它也需要增加。 - - -Modify `/etc/kubernetes/manifest/kube-controller-manager.yaml`: - -``` ---node-cidr-mask-size=21 //log2(集群中的最大pod数) ---kube-api-burst=3000 ---kube-api-qps=3000 -``` - -#### kubelet - -在单个工作节点中,我们可以默认运行110个pod。 但是为了获得更高的节点资源利用率,我们需要在Kubelet启动命令中添加一些参数,然后重启它。 - -修改`/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`中的起始参数,在起始参数后面添加`--max-Pods=300`并重启。 - -``` -systemctl daemon-reload -systemctl restart kubelet -``` - ---- - -## 概括 - -借助Kubemark和Prometheus,我们可以轻松运行基准测试、收集YuniKorn指标并分析性能。 这有助于我们识别调度程序中的性能瓶颈并进一步消除它们。 YuniKorn社区未来将继续改进这些工具,并继续获得更多的性能改进。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/profiling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/profiling.md deleted file mode 100644 index eb2ae74421a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/performance/profiling.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: profiling -title: 分析 ---- - - - -使用[pprof](https://github.com/google/pprof)做CPU,Memory profiling可以帮助你了解YuniKorn调度器的运行状态。YuniKorn REST服务中添加了分析工具,我们可以轻松地从HTTP端点检索和分析它们。 - -## CPU 分析 - -在这一步,确保你已经运行了YuniKorn,它可以通过`make run`命令从本地运行,也可以部署为在K8s内运行的pod。 然后运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/profile -``` - -配置文件数据将保存在本地文件系统中,一旦完成,它就会进入交互模式。 现在您可以运行分析命令,例如 - -``` -(pprof) top -Showing nodes accounting for 14380ms, 44.85% of 32060ms total -Dropped 145 nodes (cum <= 160.30ms) -Showing top 10 nodes out of 106 - flat flat% sum% cum cum% - 2130ms 6.64% 6.64% 2130ms 6.64% __tsan_read - 1950ms 6.08% 12.73% 1950ms 6.08% __tsan::MetaMap::FreeRange - 1920ms 5.99% 18.71% 1920ms 5.99% __tsan::MetaMap::GetAndLock - 1900ms 5.93% 24.64% 1900ms 5.93% racecall - 1290ms 4.02% 28.67% 1290ms 4.02% __tsan_write - 1090ms 3.40% 32.06% 3270ms 10.20% runtime.mallocgc - 1080ms 3.37% 35.43% 1080ms 3.37% __tsan_func_enter - 1020ms 3.18% 38.62% 1120ms 3.49% runtime.scanobject - 1010ms 3.15% 41.77% 1010ms 3.15% runtime.nanotime - 990ms 3.09% 44.85% 990ms 3.09% __tsan::DenseSlabAlloc::Refill -``` - -您可以键入诸如`web`或`gif`之类的命令来获得可以更好地帮助您的图表 -了解关键代码路径的整体性能。 你可以得到一些东西 -如下所示: - -![CPU Profiling](./../assets/cpu_profile.jpg) - -注意,要使用这些选项,您需要先安装虚拟化工具`graphviz`,如果您使用的是 Mac,只需运行`brew install graphviz`,更多信息请参考[这里](https://graphviz. gitlab.io/)。 - -## 内存分析 - -同样,您可以运行 - -``` -go tool pprof http://localhost:9080/debug/pprof/heap -``` - -这将返回当前堆的快照,允许我们检查内存使用情况。 进入交互模式后,您可以运行一些有用的命令。 比如top可以列出top内存消耗的对象。 -``` -(pprof) top -Showing nodes accounting for 83.58MB, 98.82% of 84.58MB total -Showing top 10 nodes out of 86 - flat flat% sum% cum cum% - 32MB 37.84% 37.84% 32MB 37.84% github.com/apache/yunikorn-core/pkg/cache.NewClusterInfo - 16MB 18.92% 56.75% 16MB 18.92% github.com/apache/yunikorn-core/pkg/rmproxy.NewRMProxy - 16MB 18.92% 75.67% 16MB 18.92% github.com/apache/yunikorn-core/pkg/scheduler.NewScheduler - 16MB 18.92% 94.59% 16MB 18.92% github.com/apache/yunikorn-k8shim/pkg/dispatcher.init.0.func1 - 1.04MB 1.23% 95.81% 1.04MB 1.23% k8s.io/apimachinery/pkg/runtime.(*Scheme).AddKnownTypeWithName - 0.52MB 0.61% 96.43% 0.52MB 0.61% github.com/gogo/protobuf/proto.RegisterType - 0.51MB 0.61% 97.04% 0.51MB 0.61% sync.(*Map).Store - 0.50MB 0.6% 97.63% 0.50MB 0.6% regexp.onePassCopy - 0.50MB 0.59% 98.23% 0.50MB 0.59% github.com/json-iterator/go.(*Iterator).ReadString - 0.50MB 0.59% 98.82% 0.50MB 0.59% text/template/parse.(*Tree).newText -``` - -您还可以运行 `web`、`pdf` 或 `gif` 命令来获取堆图形。 - -## 下载分析样本并在本地进行分析 - -我们在调度程序docker映像中包含了基本的go/go-tool二进制文件,您应该能够进行一些基本的分析 -docker容器内的分析。 但是,如果您想深入研究一些问题,最好进行分析 -本地。 然后您需要先将示例文件复制到本地环境。 复制文件的命令如下: - -``` -kubectl cp ${SCHEDULER_POD_NAME}:${SAMPLE_PATH_IN_DOCKER_CONTAINER} ${LOCAL_COPY_PATH} -``` - -例如 - -``` -kubectl cp yunikorn-scheduler-cf8f8dd8-6szh5:/root/pprof/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -在本地环境中获取文件后,您可以运行“pprof”命令进行分析。 - -``` -go tool pprof /Users/wyang/Downloads/pprof.k8s_yunikorn_scheduler.samples.cpu.001.pb.gz -``` - -## 资源 - -* pprof 文档 https://github.com/google/pprof/tree/master/doc。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/acls.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/acls.md deleted file mode 100644 index fa480133424..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/acls.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: acls -title: ACLs ---- - - - -:::info -用户信息通过 [这里](usergroup_resolution) 定义的方法从 kubernetes shim 传递给 Yunikorn core。 -::: - -## 使用方法 -访问控制列表对 YuniKorn 来说是通用的。 -它们可以在 YuniKorn 的多个地方使用。 -目前的使用情况仅限于队列 ACL。 - -访问控制列表允许对列表中指定的用户和组进行访问。 -他们不提供明确删除或拒绝访问列表中指定的用户和组的可能性。 - -如果没有配置访问控制列表,默认情况下访问是 *拒绝* 的。 - -## 语法 -访问控制列表的定义如下: -``` -ACL ::= “*” | userlist [ “ “ grouplist ] -userlist ::= “” | user { “,” user } -grouplist ::= “” | group { “,” group } -``` - -这个定义指定了一个通配符 *,结果是每个人都可以访问。 - -如果用户列表为空,组列表为空,则没有人可以访问。 -拒绝所有的 ACL 有两种可能的表现形式: -* 一个空的访问控制列表。(隐式) -* 一个空格(显式) - - -## 示例配置 - -### 简单示例 -一个只允许用户 `sue` 访问的 ACL -```yaml - adminacl: sue -``` -其他人不会得到访问权,这仅适用于 `sue`。 -`john` 和 `bob` 将被拒绝访问。 - -一个允许用户 `sue` 和组 `dev` 成员访问的 ACL。 -```yaml - adminacl: sue dev -``` -用户 `sue` 根据她在ACL的用户部分的明确提及而获得访问权。 -尽管她不是 `dev` 组的成员。她的组员身份是不相关的。 - -名为 `john` 的用户是 `dev` 组的成员,他将被允许根据他的组员身份进行访问。 -第三个用户叫 `bob` ,他没有被明确提到,也不是 `dev` 组的成员,将被拒绝访问。 - -一个允许访问 `dev` 和 `test` 组成员的 ACL。 -```yaml - adminacl: " dev,test" -``` -ACL必须以空格开始,表示没有用户列表。 -如果ACL没有正确引用,空格会被 yaml 解析器删除。 -由于用户列表是空的,除非他们是 `dev` 或 `test` 组的成员,否则没有一个用户会得到访问权。 - -看一下和之前一样的三个用户: -用户 `sue` 不是任何一个组的成员,被拒绝访问。 -名为 `john` 的用户是 `dev` 组的成员,根据他的组员身份,他将被允许访问。 -`bob` 不是 `dev` 组的成员。由于其为 test 的成员,所以 `bob` 将被允许访问。 - -### 转义和引号 -ACL 目前是在队列配置中实现的,它使用一个 yaml 文件。 -这对如何转义值有一些限制。 -不正确的引号值将导致 yaml 解析错误,或者可能导致对值的不正确解释。 - -以下几点需要考虑到: -1. 通配符条目必须在 yaml 配置中加引号。 -1. 一个简单的用户列表,无论它后面是否有一个组的列表,都不需要加引号,但可以加引号。 -1. 一个没有用户列表,只有一个或多个组的 ACL 必须加引号,以找到起始空间: - -正确引用 ACL 的例子 -```yaml -partitions: - - name: default - queues: - - name: test - submitacl: "*" - adminacl: sue dev,test - - name: product - submitacl: " product" -``` - -## 访问检查 -访问检查遵循以下模式: -* 检查 ACL 是否是通配符 -* 检查该用户是否在用户列表中 -* 检查该用户所属的任何组是否是组列表的一部分 - -如果检查匹配,ACL 允许访问并停止检查。 -如果没有一个检查匹配,则 ACL 拒绝访问。 - -## 用户和组信息 -对于用户和组的解决,请遵循 [这里](usergroup_resolution) 定义的说明 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/deployment_modes.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/deployment_modes.md deleted file mode 100644 index b33e1502aa1..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/deployment_modes.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -id: deployment_modes -title: 部署模式 ---- - - - -## YuniKorn部署模式 - -YuniKorn有两种部署模式: `标准模式`与`插件模式`。 -在标准模式下,YuniKorn作为自定义模式运行Kubernetes调度程序。 -在插件模式下,YuniKorn被实现为默认Kubernetes调度框架之上的一组插件。 - -在这两种情况下,建议同时运行准入控制器(admin controller),这会确保只有一个调度程序在您的Kubernetes集群中处于活动状态。 -当准入控制器运行时,所有pod将会绕过Kubernetes的默认调度器,除了YuniKorn本身的pod。 - -## 应该使用哪个版本? - -### 标准模式(Standard) - -目前的默认模式是标准模式。 标准模式提供稳定、高效、良好性能。 -当pod利用YuniKorn的队列功能,此模式非常适合大多数此类部署。 - -### 插件模式(Plugin) - -插件模式是一种新的部署模型,调度器是在默认的Kubernetes调度逻辑之上实现的,可以更好地兼容默认的Kubernetes调度器。 -它非常适合混合工作负载,如传统的Kubernetes以及排队的应用程序。 - -插件模式目前非常新,因此还没有达到标准模式的成熟度。 - -要在使用 Helm 部署时激活插件模式,请将变量`enableSchedulerPlugin`设置为`true`。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/gang_scheduling.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/gang_scheduling.md deleted file mode 100644 index 754e29c3293..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/gang_scheduling.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -id: gang_scheduling -title: 分组调度 ---- - - - -## 什么是分组调度 - -当分组调度被启用时,YuniKorn 只在以下情况下调度应用程序 -应用程序的最小资源请求能够得到满足时才会调度。否则,应用程序 -将在队列中等待。应用程序被排在层次队列中、 -启用分组调度后,每个资源队列都被分配有 -在保证最小资源的情况下,每个资源队列都被分配了最大数量的应用程序并发运行。 - -![分组调度](./../assets/gang_scheduling_intro.png) - -## 启用分组调度 - -启用分组调度不需要在集群范围内进行配置。 -调度器会主动监控每个应用的元数据,如果该应用包含了 -一个有效的任务组定义,它就会被认为是所需的分组调度。 - -:::info 任务组 -一个任务组是一个应用程序中的任务 "群组",这些任务具有相同的资源概况 -和相同的放置限制。它们被认为是同质化的请求,在调度器中可以被视为 -在调度器中被当作同一类请求处理。 -::: - -### 前提 - -对于运行支持调度的应用程序的队列,队列排序策略应该被设置为 "FIFO"。 -要配置队列排序策略,请参考文档:[应用程序排序](user_guide/sorting_policies.md#应用程序排序)。 - -#### 为什么要使用 "FIFO" 排序策略? - -当分组调度被启用时,调度器会主动为每个应用程序保留资源。 -如果队列排序策略不是基于FIFO(StateAware 是基于 FIFO 的排序策略)、 -调度器可能会为每个应用保留部分资源并导致资源分割问题。 - -#### "StateAware" 排序策略的副作用 - -我们不建议使用 `StateAware`,尽管它是一个基于 FIFO 的策略。第一个 pod 的失败或者该 pod 的初始化时间过长都会使处理过程变慢。 -当驱动在请求执行器之前进行大量的预处理时,尤其是 Spark。 -在这些情况下,`StateAware` 超时会使处理速度减慢到每次超时只有一个应用程序。 -这实际上会推翻群组的保留,并导致减速和过度使用资源。 - -### 应用程序配置 - -在 Kubernetes 上,YuniKorn 通过从单个pod加载元数据来发现应用,应用的第一个pod -被要求附上一份完整的应用元数据副本。如果应用程序没有关于第一个或第二个pod的任何注释, -那么所有的pod都需要携带相同的 taskGroups 信息。分组調度需要 taskGroups 的定义, -可以通过 pod 注解来指定。所需的字段是: - -| 注释 | 价值 | -|-----|------| -| yunikorn.apache.org/task-group-name | 任务组名称,在应用程序中必须是唯一的。 | -| yunikorn.apache.org/task-groups | 任务组的列表,每一项都包含了为该任务组定义的所有信息。 | -| yunikorn.apache.org/schedulingPolicyParameters | 可选。一个任意的键值对来定义调度策略参数。请阅读[调度策略参数](#调度策略参数) | - -#### 需要多少个任务组? - -这取决于这个应用程序向 K8s 请求多少不同类型的 pod。一个任务组是一个应用程序中的任务 "群组"、 -这些任务具有相同的资源概况和相同的放置限制。它们被认为是同质的 -在调度器中可以被视为同类的请求。以 Spark 为例,每个作业都需要有2个任务组、 -一个用于driver pod,另一个用于 executor pods。 - -#### 如何定义任务组? - -任务组的定义是应用程序的真实pod定义的副本,像资源、节点选择器、容忍度 -和亲和力应该与真正的pod相同。这是为了确保调度器能够以准确的pod规格保留资源。 -确切正确的pod规范。 - -#### 调度策略参数 - -调度策略相关的可配置参数。在pod的注释中以下列格式应用这些参数: - -```yaml -annotations: - yunikorn.apache.org/schedulingPolicyParameters: "PARAM1=VALUE1 PARAM2=VALUE2 ..." -``` - -目前,支持以下参数: - -`placeholderTimeoutInSeconds` - -默认值: *15分钟*。 -这个参数定义了预约超时,即调度器在放弃分配所有占位符之前应该等待多长时间。 -当调度器*分配第一个占位器pod*时,超时计时器开始计时。这确保了如果调度器 -无法调度所有的占位荚,它最终会在一定的时间后放弃。这样,资源可以被 -释放出来,供其他应用程序使用。如果没有占位符可以被分配,这个超时就不会启动。为了避免占位符 -pods永远卡住,请参考 [故障排除](troubleshooting.md#成组调度) 了解解决方案。 - -`gangSchedulingStyle` - -有效值: *Soft*, *Hard* - -默认值:*Soft*. -这个参数定义了当应用程序由于占位符 pod 分配而遇到分组问题时的后退机制。 -更多细节见[分组调度风格](#分组调度风格)部分 - -更多的调度参数将被添加,以便在调度应用程序时提供更多的灵活性。 - -#### 示例 - -下面的例子是一个工作的yaml文件。这个工作启动了2个 pod,每个 pod 睡眠时间为 30 秒。 -在 pod 规范中值得注意的变化是 *spec.template.metadata.annotations*,在这里我们定义了 `yunikorn.apache.org/task-group-name -和 `yunikorn.apache.org/task-groups` 。 - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-scheduling-job-example -spec: - completions: 2 - parallelism: 2 - template: - metadata: - labels: - app: sleep - applicationId: "gang-scheduling-job-example" - queue: root.sandbox - annotations: - yunikorn.apache.org/task-group-name: task-group-example - yunikorn.apache.org/task-groups: |- - [{ - "name": "task-group-example", - "minMember": 2, - "minResource": { - "cpu": "100m", - "memory": "50M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "50M" -``` - -当这项工作提交给 Kubernetes 时,将使用同一模板创建2个pod,它们都属于一个任务组: -*"task-group-example"*。 YuniKorn将创建2个占位符pod,每个都使用任务组定义中指定的资源。 -当所有2个占位符分配完毕后,调度器将使用占位符保留的位置来绑定真正的2个睡眠pods。 - -如果有必要,你可以添加多个任务组,每个任务组由任务组名称标识、 -通过设置任务组名称,需要将每个真实的pod与一个预先定义的任务组进行映射。注意、 -任务组名称只要求在一个应用程序中是唯一的。 - - -### 启用Spark作业的Gang调度 - -每个Spark作业都运行2种类型的pod,驱动和执行器。因此,我们需要为每个作业定义2个任务组。 -驱动器pod的注释看起来像: - -```yaml -Annotations: - yunikorn.apache.org/schedulingPolicyParameters: “placeholderTimeoutSeconds=30” - yunikorn.apache.org/taskGroupName: “spark-driver” - yunikorn.apache.org/taskGroup: “ - TaskGroups: [ - { - Name: “spark-driver”, - minMember: 1, - minResource: { - Cpu: 1, - Memory: 2Gi - }, - Node-selector: ..., - Tolerations: ..., - Affinity: ... - }, - { - Name: “spark-executor”, - minMember: 10, - minResource: { - Cpu: 1, - Memory: 2Gi - } - } - ] - ” -``` - -:::note -任务组的资源必须考虑到Spark驱动和执行器的内存开销。 -参见 [Spark documentation](https://spark.apache.org/docs/latest/configuration.html#application-properties) 以了解如何计算这些数值的细节。 -::: - -对于所有的执行者 pod, - -```yaml -Annotations: - # 任务组字段中定义的名称相匹配 - # 在任务组字段中定义 - yunikorn.apache.org/taskGroupName: “spark-executor” -``` - -一旦工作被提交给调度器,工作就不会被立即调度。 -相反,在实际启动驱动/执行器之前,调度器将确保它获得最小的资源。 - -## 分组调度风格 - -有2种分组调度方式支持,分别是 Soft 和 Hard。它可以在每个应用层面进行配置,以定义应用在分组调度失败时的行为。 - -- `Hard Style`:当使用这种风格时,我们将有初始行为,更确切地说,如果应用程序不能根据分组调度规则进行调度,并且超时,它将被标记为失败,而不会重新尝试调度。 -- `Soft Style`:当应用程序不能被分组调度时,它将退回到正常的调度,并使用非分组调度策略来实现最佳努力的调度。当这种情况发生时,应用程序将过渡到恢复状态,所有剩余的占位符 pod 将被清理掉。 - -**使用的默认样式**: ``Soft。 - -**启用一个特定的风格**:可以通过在应用程序定义中设置'gangSchedulingStyle'参数来改变风格,即 Soft 或 Hard。 - -#### Example - -```yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: gang-app-timeout -spec: - completions: 4 - parallelism: 4 - template: - metadata: - labels: - app: sleep - applicationId: gang-app-timeout - queue: fifo - annotations: - yunikorn.apache.org/task-group-name: sched-style - yunikorn.apache.org/schedulingPolicyParameters: "placeholderTimeoutInSeconds=60 gangSchedulingStyle=Hard" - yunikorn.apache.org/task-groups: |- - [{ - "name": "sched-style", - "minMember": 4, - "minResource": { - "cpu": "1", - "memory": "1000M" - }, - "nodeSelector": {}, - "tolerations": [], - "affinity": {} - }] - spec: - schedulerName: yunikorn - restartPolicy: Never - containers: - - name: sleep30 - image: "alpine:latest" - imagePullPolicy: "IfNotPresent" - command: ["sleep", "30"] - resources: - requests: - cpu: "1" - memory: "1000M" - -``` - -## 验证配置 - -为了验证配置是否已经完全正确,请检查以下事项: -1. 当一个应用程序被提交时,验证预期的占位符数量是否被调度器创建。 -如果你定义了两个任务组,一个是minMember 1,另一个是minMember 5,这意味着我们期望在任务提交后有6个占位符被创建。 -被创建。 -2. 验证占位符的规格是否正确。每个占位符都需要有与同一任务组中的真实pod相同的信息。 -检查领域包括:命名空间、pod资源、节点选择器、容忍度和亲和力。 -3. 验证占位符可以分配到正确的节点类型上,并验证真正的pod是通过替换占位符pod而启动的。 - -## 故障排除 - -请参阅启用帮派调度时的故障排除文档 [這裡](troubleshooting.md#成组调度) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/labels_and_annotations_in_yunikorn.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/labels_and_annotations_in_yunikorn.md deleted file mode 100644 index e8d1df930fb..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/labels_and_annotations_in_yunikorn.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -id: labels_and_annotations_in_yunikorn -title: 标签和注释 ---- - - -## YuniKorn 中的标签和注释 -YuniKorn 利用了几个 Kubernetes 标签和注释来支持各种功能: - -### YuniKorn 的标签 -| 名称 | 说明 | -| ------------------- | ---------------------------- | -| `applicationId` | 将这个 Pod 与一个应用程序联系起来。| -| `queue` | 选择这个应用程序应该被安排在哪个 YuniKorn 队列中。如果有放置策略,这可能被忽略。| -| `SparkLabelAppID ` | 如果标签 `applicationId` 和注解 `yunikorn.apache.org/app-id` 未设置,Spark Operator 使用的指定 `applicationId` 的替代方法。| -| `disableStateAware` | 如果存在,则禁用该 pod 的 YuniKorn 状态感知调度策略。由 YuniKorn 接纳控制器内部设置。| -| `placeholder` | 设置该 pod 是否代表分组调度的占位符。由 YuniKorn 内部设置。| - -### YuniKorn 中的注解 -所有注解都在 `yunikorn.apache.org` 的命名空间下。例如 `yunikorn.apache.org/app-id` 。 - -| Name | Description | -| ------------------------------ | ------------------ | -| `app-id` | 将这个pod与一个应用程序联系起来。
应用ID的优先级由以下因素决定:注释 `yunikorn.apache.org/app-id` > 标签 `applicationId` > 标签 `SparkLabelAppID`。| -| `queue` | 选择这个应用程序应该被安排在YuniKorn队列中。
队列的优先级由以下因素决定:标签 `queue` >注释 `yunikorn.apache.org/queue` >默认。| -| `task-group-name` | 设置这个pod所属的任务组名称,以便进行分组调度。它必须列在`task-groups`中。| -| `task-groups` | 定义了这个应用程序的任务组集合,用于分组调度。一个应用程序中的每个pod必须定义所有的任务组。| -| `schedulingPolicyParameters` | 任意的键值对,用于定制调度策略,如分组调度。 | -| `placeholder` | 设置该pod是否代表分组调度的占位符。由YuniKorn内部设置。 | -| `allow-preemption` | `allow-preemption'注解只能设置在PriorityClass对象上。它将触发对具有该特定优先级类的pod的选择退出抢占。进一步的细节可以在[使用简单的抢占器进行 DaemonSet 调度](../design/simple_preemptor)文档中找到。 | -| `parentqueue` | 为一组K8s命名空间定义一个父队列。进一步的细节可以在[资源配额管理](resource_quota_management#命名空间的父队列映射)文档中找到。 | -| `namespace.quota` | 设置映射到该命名空间的队列的最大容量。进一步的细节可以在[资源配额管理](resource_quota_management#命名空间配额)文档中找到。 | -| [已删除] `namespace.max.cpu` | 从1.2.0版开始,用 `namespace.quota` 代替。 | -| [已删除] `namespace.max.memory` | 自1.2.0版起被`namespace.quota`取代。 | -| `namespace.enableYuniKorn` | 控制哪些命名空间的pod将被转发给Yunikorn进行调度。进一步的细节可以在[服务配置#准入控制器过滤设置](service_config#准入控制器过滤设置)文档中找到。 | -| `namespace.generateAppId` | 控制哪些命名空间将有标有 `applicationId` 的 pod。进一步的细节可以在[服务配置#准入控制器过滤设置](service_config#准入控制器过滤设置)文档中找到。 | - -关于分组调度的标签和注释的更多细节,请参考[分组调度](../user_guide/gang_scheduling.md)的文档。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/placement_rules.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/placement_rules.md deleted file mode 100644 index 17ccd279c87..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/placement_rules.md +++ /dev/null @@ -1,296 +0,0 @@ ---- -id: placement_rules -title: App 放置规则 ---- - - -基础的放置规则(placement rules)配置[调度弃配置设计文档](../design/scheduler_configuration#placement-rules-definition)中有相关描述。 - -我们可以将多个规则链结再一起形成一个放置策略,并通过[存取控制列表(Access control lists)](user_guide/acls.md)和规则过滤来定义和执行规则。 - -本篇文章将通过例子来解释如何建立策略以及规则的使用,而该放置策略为调度器的一部分。 - -## 配置 -放置规则作为调度程序队列配置的一部分,可以在各分区(partition)中被定义。规则定义的顺序就是他们会被执行的顺序。如果一个规则匹配,策略会停止执行剩余的规则。 - -匹配的放置规则会产生一个完全合格的队列名称。同时这个回传的队列名称会从根队列(root)开始。而在队列层次结构中,可以生成的层次数量没有限制。 - -当要执行一条规则时,已经被执行过的规则不会被列入考虑;这条规则也不会对往后要执行的规则有所影响:规则不能影响其他的规则,除非它们被配置为父规则([parent](#parent-参数))。 - -当放置策略没有生成队列名称且没有更多的规则时,应用程式将会被拒绝。 - -在配置中,定义放置规则的基本结构如下: -```yaml -placementrules: - - name: <第一条放置规则的名称> - - name: <第二条放置规则的名称> -``` -每个[规则](#规则)都可以在配置中采取一套预定义的参数。可以被使用的规则名称在规则描述中提及。规则名称在配置中不区分大小写,且必须遵从以下的命名惯例: -* 从字母开始:a-z 或 A-Z -* 后面跟着0或多个字元 a-z, A-Z, 0-9 或 _ - -当规则名称没有对应到任何已定义的规则时,表示规则处于未知的状态,会造成放置管理器初始化错误。如果参数不正确,会抛出解析错误或在初始化时发生错误。一个有错误的规则集永远不可能被激活。 - -如果放置管理器中含有一个被激活的规则集,就代表他已经初始化了。重新载入时,若配置了一个新的规则集时,就会将新的规则集激活,并取代旧有的。如果新规则集包含一个错误,放置管理器就会忽视这个新规则集,同时也持续处于「使用不完全的规则集」的状态。如果放置管理器持续使用已激活的规则集,忽视新的且有错误的规则集时,则会记录一条关于坏掉且被忽视的配置信息。 - -规则结果中的「点 "."」,会被文字的「"\_dot\_"」所替代。而「点」会被取代是因为在完全限定的队列名称中,他是被用来分隔队列层次的。而替代过程是发生在建构完整队列层次,且结果合格之前。这代表我们允许用「点」来表达用户名或标籤值,但不影响到队列层次。举例来说,当配置中的队列对应到「含有点的用户名」时,你必须要使用以下方法来指定它们:如果一个用户名称为`user.name`且使用`user`规则,则会产生队列名称为`root.user_dot_name`的队列。而如果该用户队列必须事先被加到配置中,则也该使用`user_dot_name`这个名字。 - -### Create 参数 -create 参数是一个布林值,会定义当一个队列不存在时,是否可以在规则的定义下创建队列。不能保证队列一定会被创建,因为现有的队列可能会阻止创建。但如果规则定义下想创建的队列不存在,且`create: false`,那结果将会是创建失败。 - -带有`create`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - create: true -``` -预设值为`false`。允许的值为`true`或`false`,其他值均会导致显示错误。 - -### Parent 参数 -`parent` 参数允许指定一个规则,并为他产生一个父队列。父规则可以被嵌套,一个父规则可以包含另一个父规则,此外对于父规则的嵌套也没有强制限制。 - -父规则被视为顶层的规则,因此具有与放置定义中任何其他规则相同的参数和需求。例外的情况是,在「已经生成完全合格队列」的规则上再使用父规则,被认为是一个配置错误。这个错误只能发生在`fixed`型的规则上,查看规范可以得到更多细节。 - -注意:规则的执行会沿着父规则的列表向下遍历,并首先执行列表中的最后一条。代表最后一条父规则将会直接产生在根部,详见示例。 - -带有`parent`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - parent: - name: <父规则的名称> -``` -预设值中没有parent参数。 - -### Filter 参数 -通过`filter`参数的定义,能过滤掉适用的用户来进行配置。过滤器是一个复杂的配置組件。 - -用户和群组可以被配置为两种类别: -* 正则表达式 -* 用户或群组的列表 - -如果用户或群组在yaml中的条目超过一个,则就会被视为一个用户列表或群组列表。列表中重复的条目会被忽略,不会引起错误。依据其他列表元素来使用正则表达式是不被允许的。 - -用户和群组名称遵循标准的Linux 用户和群组惯例,对于用户名来说: -* 从一个字母作为开头:a-z 或 A-Z -* 后面跟着0或更多个字符:a-z, A-Z, 0-9 或 _ . @ - -* 最后一个字符可以式$ - -对于群组名来说: -* 从一个字母作为开头:a-z 或 A-Z -* 后面跟着0或更多个字符:a-z, A-Z, 0-9 或 _ - - -如果列表中正好有一个条目,他可以是单个用户、群组或正则表达式。当一个条目包含一个在用户或群组中不允许的字符时,该条目会被认为是一个正则表达式。正则表达式必须按照规定进行编译。一个不能编译的正则表达式将会被忽略。 - -此外针对群组的正则表达式中:每次都是针对一个组进行匹配,而不是针对组的列表。 - -带有 `filter`参数的简易yaml范例: -```yaml -filter: - type: deny - users: - - - - - groups: - - - - -``` -预设值中没有filter参数。 - -### Value 参数 -这是一个通用值,用来传递给规则以实现或改变其行为。该值被用来与[fixed](#fixed-rule)和[tag](#tag-rule)型的规则一起使用。此外`value`是以字串型式存在的单一值,也不会被系统解释或干扰。 - -带有 `value`参数的简易yaml范例: -```yaml -placementrules: - - name: <放置规则的名称> - value: "any string" -``` -预设值中没有value参数。 - -## 准入控制列表 -准入控制列表没有在规则中定义,但它们影响放置策略的结果。有两种准入控制列表可以被定义到队列上: -1. 提交ACL: `submitacl` -2. 管理ACL: `adminacl` - -如果队列的ACL允许任何ACL提交存取,则放置规则才能匹配。管理队列ACL还提供「提交准入」的功能。如果队列不存在或没有配置ACL,则将检查父队列的ACL。这种递迴的检查会重复执行,直到有ACL提供存取或根目录的ACL被检查过后。 - -关于ACL语法的更多细节,请查阅[ACL文档](user_guide/acls.md)。 - -## 规则 -### Provided Rule -在配置中使用的名称:*provided* - -提供在提交应用时所指定的队列。本规则的行为是─如果队列不完全合格,则完全限定由「应用程序提供的队列」作为放置的队列。如果设置了一个父规则,并且在应用程序提交中提供的队列是完全合格的,那麽父规则就不会被执行。 - -支持的参数: -* create -* parent -* filter - -举例:如果用户名下不存在队列,则用户传入的队列会被创建。 -```yaml -placementrules: - - name: provided - create: true - parent: - name: user - create: true -``` -当用户 `developer` 向应用程式提交请求,且应用程式要求的队列名称为:`my_special_queue`。
-结果:`root.developer.my_special_queue`(父规则将设置用户名称)。 - -当用户 `developer` 向应用程式提交请求,且应用程式要求的队列名称为:`root.dev_queue`。
-结果:`root.dev_queue`(父规则将被忽视)。 - -### User Name Rule -在配置中使用的名称:*user* - -提供一个基于用户名的队列,而该用户名为所提交的应用程序的一部分。 - -支持的参数: -* create -* parent -* filter - -举例:提交一个基于用户名的队列,如果队列不存在,不要创建队列。 -```yaml -placementrules: - - name: user - create: false -``` - -当用户`finance.test`提交了一个应用程式,此外对应的队列也存在。
-结果: `root.finance_dot_test`(注意,「点」被替换了)。 - -当用户`developer`提交了一个应用程式,但对映的队列不存在。
-结果:失败,执行下一条规则。 - -### Fixed Rule -在配置中使用的名称:*fixed* - -回传一个队列,其依据规则参数的值作为名称,配置的值必须是一个合法的队列名称或层次结构。该队列名称不一定需要完全合格。名称中的层次结构使用「一个点(.)」作为层次结构中不同级别的分隔符。只有当配置的队列不存在且`create`标籤未设置时,`fixed`规则才会失败,因为他始终新增一个配置的队列。 - -支持的参数: -* value(reuqired) -* create -* parent -* filter - -举例:因为总是会回传一个队列,若没有设置`create`标籤,则要在配置中将队列定义为子队列。 -```yaml -placementrules: - - name: fixed - value: last_resort -``` - -当用户 `developer`提交请求,且在应用程式中设定的队列为:`my_special_queue` 。
-结果:`root.last_resort`。 - -### Tag Rule -在配置中使用的名称:*tag* - -从应用程式的标籤中检索队列名称。检查`tag`的值(value),并在规则中使用该值进行配置。若`tag`规则没有包含任何值,则代表配置错误,但是一个应用程式不一定要设置该值。 - -如果应用程序上没有设置对应的`tag`,则规则失败。如果从应用程序回传的`tag` value是一个完全限定的队列名称,则父规则(如果已配置)将不会执行。 - -支持的参数: -* value(reuqired) -* create -* parent -* filter - -举例:根据kubernetes命名空间放置一个应用程序,该命名空间在提交时自动在应用程序中设置。 -```yaml -placementrules: - - name: tag - value: namespace - create: true -``` - -用户`developer`在命名空间`default`,提交基于kubernetes的应用程序请求,且在应用程是中设定的队列为:`my_pecial_queue`。
-结果:`root.default`。 - -用户`developer`在命名空间`testing`,提交基于kubernetes的应用程序请求,且在应用程是中设定的队列为:`my_pecial_queue`。
-结果:`root.testing`。 - -用户提交非基于kubernetes的应用程序请求。
-结果:失败,执行下一条规则。 - -## 复杂的例子 -在这个复杂的例子中,我们串连了三个规则: - -1. 一个`user`规则,其父规则标籤使用kubernetes命名空间,且仅供`dev`群组内的用户。 -2. 一个`tag`规则,使用kubernetes命名空间,其`parent`规则固定使用已存在的队列─ `root.namespaces`。 -3. 一个`fixed`规则,将所有到达这个点的应用程序都放在`root.default`队列中。 - -举例: -```yaml -placementrules: - - name: user - create: true - filter: - type: allow - groups: - - dev* - parent: - - name: tag - value: namespace - - name: tag - value: namespace - create: true - parent: - - name: fixed - value: root.namespaces - filter: - type: allow - users: - - john - - name: fixed - value: root.default -``` -用户`john`在命名空间testing中提交基于kubernetes应用程序的请求。
-结果:`root.namespaces.testing`(在规则2中匹配)。 - -用户`sarah`在命名空间`newapp`中提交基于kubernetes应用程序的请求,组员为`sarah`, `test_app`, `dev_app`。
-结果:`root.newapp.sarah`(在规则1中匹配)。 - -用户bob在命名空间`testapp`中提交基于kubernetes应用程序的请求,组别成员为`bob`。
-结果:`root.default`(在规则3中匹配)。 -
-在第二个例子中,我们使用了两条规则。 - -1. 一个`fixed`规则,将所有东西放在`root.production`队列中。 -2. 一个`user`规则,以及设置 `create` 标籤。 - -但在这个例子中,我们在`root.production`的队列上设置了ACL,只允许两个特定的用户使用这个队列。因此,即使规则匹配,除非是`john`或`bob`,否则应用程式将不会被放在`production`队列中。所有其他用户将匹配第二条规则并使用它们自己的队列,如果队列不存在,就会创建。 - -```yaml -partitions: - - name: default - queues: - - name: production - submitacl: john,bob - placementrules: - - name: fixed - value: root.production - - name: user - create: true -``` diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/prometheus.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/prometheus.md deleted file mode 100644 index 4ded82ff1f1..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/prometheus.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: prometheus -title: Setting Prometheus ---- - - - -YuniKorn exposes its scheduling metrics via Prometheus. Thus, we need to set up a Prometheus server to collect these metrics. - -If you don't know what metric can be used, you can use [REST API](../api/scheduler.md#指标(Metrics)). - -### 1. **Download Prometheus release** - -```bash -wget https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz -``` - -```bash -tar xvfz prometheus-*.tar.gz -cd prometheus-* -``` - -### 2. **Configure prometheus.yml** - -Prometheus collects metrics from *targets* by scraping metrics HTTP endpoints. - -```yaml -global: - scrape_interval: 3s - evaluation_interval: 15s - -scrape_configs: - - job_name: 'yunikorn' - scrape_interval: 1s - metrics_path: '/ws/v1/metrics' - static_configs: - - targets: ['localhost:9080'] - # 9080 is internal port, need port forward or modify 9080 to service's port -``` - -### 3. Start port-forward - -Port forwarding for the core's web service on the standard port can be turned on via: - -```bash -kubectl port-forward svc/yunikorn-service 9080:9080 -n yunikorn -``` - -`9080`is the default port for core's web service. - -### 4. Execute prometheus - -```bash -./prometheus --config.file=prometheus.yml -``` - -![prometheus-cmd](../assets/prometheus-cmd.png) - -### 5. Access the Prometheus UI - -You should be able to browse to a status page at [localhost:9090](http://localhost:9090/). Give it a couple of seconds to collect data about itself from its own HTTP metrics endpoint. - -![prometheus-web-ui](../assets/prometheus-web-ui.png) - -You can also verify that Prometheus is serving metrics by navigating to its metrics endpoint:[localhost:9090/metrics](http://localhost:9090/metrics) \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/queue_config.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/queue_config.md deleted file mode 100644 index c8a140eba35..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/queue_config.md +++ /dev/null @@ -1,382 +0,0 @@ ---- -id: queue_config -title: 分区和队列配置 ---- - - - -队列配置基础在[配置设计文档](design/scheduler_configuration.md)中有描述。 - -本文档提供通用队列配置。 -队列配置引用了[访问控制列表](user_guide/acls.md)和[放置规则](user_guide/placement_rules.md)文档。 - -本文档通过示例说明如何为调度程序创建分区和队列配置。 - -调度程序依靠shim可靠地提供用户信息作为应用程序提交的一部分。 -当前shim使用[用户和组解析](usergroup_resolution)中提供的方法识别用户和用户所属的组。 - -## 配置 -此处描述的调度器的配置文件仅提供分区和队列的配置。 - -默认情况下,我们在部署中使用`queues.yaml`文件。 -文件名可以通过命令行更改调度器的`policyGroup`标志。 -更改文件名后必须对部署细节进行相应的更改,可以是`configmap`或包含在docker容器中的文件。 -配置的示例文件位于yunikorn-core的[queues.yaml](https://github.com/apache/yunikorn-core/blob/master/config/queues.yaml). - -## 分区 -分区(partitions)是调度器配置的最高级别。 -在配置中可以定义多个分区。 - -配置中分区定义的基本结构如下: -```yaml -partitions: - - name: <第一个分区的名称> - - name: <第二个分区的名称> -``` -分区的默认名称是`default`。 -分区定义包含特定shim相应调度器的完整配置。 -每个shim都使用自己独特的分区。 - -分区必须至少需要定义以下键: -* name -* [queues](#队列) - -队列配置会在分区结束后介绍。 - -可以选择为分区定义以下键: -* [placementrules](#放置规则) -* [statedumpfilepath](#状态转储文件路径) -* [limits](#限制) -* nodesortpolicy -* preemption - -放置规则和限制在各自的章节中解释。 - -`nodesortpolicy`定义节点为分区排序的方式。 -有关可以使用的节点排序策略值的详细信息,请参阅[排序策略](user_guide/sorting_policies.md#node-sorting)文档。 - -抢占键目前只能有一个子键: _enabled_。 -这个布林值定义了整个分区的抢占行为。 - -_enabled_的默认值为_false_。 -_enabled_的允许值:_true_或_false_,任何其他值都会导致解析错误。 - -下方的示例中,`partition` yaml条目是带有_preemption_标志集和_fair_的`nodesortpolicy`。 -```yaml -partitions: - - name: <分区名称> - nodesortpolicy: fair - preemption: - enabled: true -``` -备注: -目前,Kubernetes独特的shim不支持除`default`分区之外的任何其他分区。 -这已被记录为shim的[jira](https://issues.apache.org/jira/browse/YUNIKORN-22)。 - -### 队列 - -YuniKorn通过利用资源队列来管理资源。 -资源队列(queues)具有以下特征: -- 队列可以有**层次**结构 -- 每个队列都可以预设**最小/最大容量**,其中最小容量定义保证资源,最大容量定义资源限制(所谓的资源配额) -- 任务必须在某个`leaf`队列下运行 -- 队列可以是**静态**(从配置文件加载)或**动态**(由YuniKorn内部管理) -- 队列级别的**资源公平**是由调度器强制执行 -- 作业只能在特定队列下运行 - -:::info -YuniKorn队列与[Kubernetes命名空间](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)的区别: -Kubernetes命名空间提供了Kubernetes资源的范围,包括安全环境(即谁可以访问对象),以及定义[资源配额](https://kubernetes.io/docs/concepts/policy/resource-quotas/)时的资源边界(即对象可以使用多少资源)。 -另一方面,YuniKorn队列仅使用一组作业可以使用多少资源,以及以何种顺序使用。 -YuniKorn队列在考虑资源公平性、作业排序等方面提供了更细粒度的多租户资源共享控制。 -在大多数情况下,YuniKorn队列可用于替代命名空间资源配额,以提供更多的调度特性。 -::: - -_queues_条目是主要的配置元素,它为队列定义了层次结构。 - -它可以定义一个`root`队列,但它不是必需的元素。 -如果未定义`root`队列,配置解析将插入root队列以保持一致性。 -以下因素会触发root队列的插入: -* 如果配置在顶层定义了多个队列,则会插入一个根队列。 -* 如果在顶层只定义了一个队列并且它不被称为`root`,则插入一个root队列。 - -定义的一个或多个队列将成为插入的`root`队列的子队列。 - -带有子队列的基本`queue` yaml条目: -```yaml -queues: -- name: <队列名称> - queues: - - name: <队列名称> -``` - -队列支持的参数: -* name -* parent -* queues -* maxapplications -* properties -* adminacl -* submitacl -* [resources](#资源) -* [limits](#限制) - -每个队列都必须有一个_name_并且队列的名称在定义队列的同一级别上必须是唯一的。 -由于队列结构是完全层次化的,层次结构中不同点的队列可能具有相同的名称。 -例如:队列结构`root.testqueue`和`root.parent.testqueue`是一个有效的结构。 -需注意的是,队列不能包含点“.”字符,因为该字符用于分隔层次结构中的队列。 -如果名称对于配置中的队列不是唯一的,或者名称包含一个点,则会生成解析错误并拒绝配置。 - -依队列的类型是否于队列有子模板队列和子队列的事实,结构中的队列将自动获得分配的类型。 -队列类型有两种: -* parent -* leaf - -应用只能分配给_leaf_队列。 -在配置中,队列具有子模板队列或子队列将自动成为_parent_队列。 -如果队列在配置中没有子队列,则该队列是_leaf_队列,除非该队列`parent`参数设置为_true_。 -尝试覆盖配置中的_parent_队列类型将导致配置解析错误。 - -parent队列的子队列在`queues`条目下定义。 -`queues`条目是队列级别的递归条目,它使用完全相同的参数集。 -_maxapplications_属性是一个大于 1 的整数值,它允许您限制队列中正在运行的应用的数量。 -不允许为_maxapplications_指定零,因为它会阻止队列中应用的任何分配。 -_子_队列的_maxapplications_值必须小于或等于_parent_队列的值。 -`properties`参数是一个简单的键值对列表,并为队列提供一组简单的属性。其中的键或值没有限制,任何东西都是允许的。 -目前,属性列表仅在调度器中用于定义leaf队列的[排序顺序](user_guide/sorting_policies.md#application-sorting)。 -在未来的扩展中,添加比如打开或关闭队列抢占或其他排序策略的选项,让使用相同的属性构造而无需更改配置。 - -通过`adminacl`设置对队列的访问权限以进行管理操作,并通过`submitacl`条目提交应用。 -访问控制列表(ACLs)的描述可见[访问控制列表(ACLs)](user_guide/acls.md)文档。 - -队列资源限制是通过`resources`参数设置。 -用户和群组的限制是通过`limits`参数设置。 -由于这两个条目都是复杂的配置条目,因此它们在下面的[resources](#资源)和[limits](#限制)中有相应解释。 - -以下示例配置是`root.namespaces`队列作为具有限制的_parent_队列: -```yaml -partitions: - - name: default - queues: - - name: namespaces - parent: true - maxapplications: 12 - resources: - guaranteed: - {memory: 1G, vcore: 10} - max: - {memory: 10G, vcore: 100} - queues: - - name: level1 - maxapplications: 8 - resources: - guaranteed: - {memory: 0.5G, vcore: 5} - max: - {memory: 5G, vcore: 50} -``` - -### 放置规则 - -放置规则(placement rules)在[放置规则](user_guide/placement_rules.md)文档中有相关定义和记录。 - -每个分区只能定义一组放置规则。 -如果没有定义规则,则放置管理器不会启动。 -此外,在提交应用时,*必须*为每个应用设置一个队列。 - -### 状态转储文件路径 - -状态转储文件路径(Statedump filepath)定义YuniKorn状态转储的输出文件并且它可以在分区级别上设置。 -如果设置转储文件路径,该字段的值可以是相对路径或绝对路径(此处相对路径是基于工作目录)。 -如果YuniKorn调度器没有足够的权限在指定路径创建状态转储文件,它将无法启动状态转储的功能。 - -```yaml -statedumpfilepath: -``` -如果上面的键没有在分区配置中指定,它的默认值为`yunikorn-state.txt`。 -需注意的是,如果键在多个分区中指定,则其第一次出现的值优先。 - -状态转储文件也有一个固定的循环策略。 -目前,每个状态转储文件的容量为10MB,最多可以有10个这样的文件。 -当前正在写入的状态转储文件将始终是上面配置的值或默认的`yunikorn-state.txt`。 -当达到文件大小限制时,日志旋转器(`lumberjack`)将通过在文件前加上时间戳来修改文件,并创建一个具有相同的无前缀名称的新文件来写入状态转储。 -如果达到状态转储文件的最大数量,轮换策略将删除根据标记时间戳的最旧文件。 - -### 限制 -限制(limits)为分区或队列定义一组限制对象,以及它可以在分区或任何级别的队列上设置。 -```yaml -limits: - - limit: <描述> - - limit: <描述> -``` - -限制对象是一个复杂的配置对象,它为一组用户和/或群组定义一个限制。 -多个独立的限制可以设置为队列或分区上一个`limits`条目的一部分。 -不属于限制设置的用户和/或群组将不受限制。 - -limits条目的示例: -```yaml -limits: - - limit: <描述> - users: - - <用户名或"*"> - - <用户名> - groups: - - <群组名称或"*"> - - <群组名称> - maxapplications: <1..最大值> - maxresources: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] -``` - -队列限制的情况下,应用递归限制。 -这意味着对`root`队列的限制是集群中用户或群组的总体限制。 -因此,`root`队列限制也等同于`partition`限制。 - -limits参数: -* limit -* users -* groups -* maxapplications -* maxresources - -_limit_参数是limits条目的可选描述。 -除了使配置易于理解和可读之外,它不用于任何其他用途。 - -可以配置的_users_和_groups_可以是以下两种类型之一: -* 一个星号字符 "*" -* users或groups的列表。 - -如果users或groups的条目包含超过1个条目,则它始终被视为users或groups的列表。 -星号字符“*”为通配符,匹配所有用户或群组。 -不允许在其他列表元素旁边指定星号字符。 -列表中的重复条目将被忽略,并不会导致解析错误。 - -_maxapplications_是一个无符号整数值。 -当_maxapplications_大于1,它允许您限制为配置的用户或群组运行的应用的数量。 -不允许指定_maxapplications_为0,因为_maxapplications_为0时,隐含拒绝任何访问。 -拒绝访问的规范应交由ACL条目处理。 - -_maxresources_参数可用于指定一个或多个资源的限制。 -_maxresources_使用与队列的[resources](#资源)参数相同的语法。 -未在列表中指定的资源不受限制。 -资源限制可以设置为 0,这可以防止用户或群组请求指定的资源,即使队列或分区具有可用的特定资源也是如此。 -不允许将总体资源限制指定为零,换言之,这意味着限制中指定的至少一个资源必须大于零。 -如果资源在队列上不可用,则应使用队列定义上的最大资源。 -指定一个实际上为零的限制,_maxapplications_ 为零并且所有资源限制为零,这是不允许的,并且会导致解析错误。 - -每个用户或群组都有一个限制,它*不是*所有用户或群组的组合限制。 - -举个例子: -```yaml -limit: "example entry" -maxapplications: 10 -users: -- sue -- bob -``` -在这种情况下,用户`sue`和`bob`都被允许运行10个应用。 - -### 资源 -队列的resources条目可以为队列设置_guaranteed_和/或_maximum_资源,yunikorn会递归地检查资源限制。 -leaf队列的资源使用量是为该队列分配的所有资源的总和。 -parent队列的资源使用量是该parent队列下面所有队列,leaf和parent队列的资源使用量的总和。 - -root队列没有_guaranteed_的资源设置。 -root队列的_max_资源限制自动等于集群大小。 -如果root队列设置了任何限制,则会发生解析错误。 -leaf队列在定义时不能设置任何资源限制。 - -配置后的_max_资源对可以在任何时间点分配给队列的所有分配的大小进行了硬性限制。 -_max_资源可以设置为0,这使得资源对队列不可用。 -_guaranteed_资源用于计算队列份额和分配期间,它用作决定将分配分配给哪个队列的输入之一。 -抢占使用队列的_guaranteed_资源作为队列不能低于的基础。 - -基本的`resources` yaml条目: -```yaml -resources: - guaranteed: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] - max: - <资源名称1>: <0..最大值>[后缀] - <资源名称2>: <0..最大值>[后缀] -``` -列表中未指定的资源不受限制,对于最大(max)资源,或在保证(guaranteed)资源的情况下保证。 - -可以为资源数量指定一个可选的后缀。 -有效的国际单位制后缀是`k`、`M`、`G`、`T`、`P` 和 `E`,用于10的幂,以及`Ki`、`Mi`、`Gi`、`Ti`、 `Pi`和`Ei`表示2的幂。 -此外,`vcore`类型的资源可能带有后缀`m`以表示millicores。 例如,`500m`是vcore的50%。 -默认情况下,`memory`类型的单位以byte为单位进行解释。 -所有其他资源类型都没有指定的基本单位。 - -注意,以上单位行为从yunikorn 1.0开始有效 -以前的版本将`memory`解释为1000000(百万)bytes的单位,将`vcore`解释为millicores。 - -### 子模板 - -子模板(child template)可以在父类型队列的队列层次结构中的任何级别来定义。 -parent队列可以提供一个模板来定义它下面的动态leaf队列的行为。 -如果parent队列定义了子模板,则没有子模板的parent队列会从其parent队列继承子模板。 - -模板中支持的配置如下所示。 -1. application sort policy -2. max resources -3. guaranteed resources -4. max applications - -举个例子: -```yaml - partitions: - - name: default - placementrules: - - name: provided - create: true - queues: - - name: root - submitacl: '*' - childtemplate: - maxapplications: 10 - properties: - application.sort.policy: stateaware - resources: - guaranteed: - vcore: 1 - memory: 1G - max: - vcore: 20 - memory: 600G - queues: - - name: parent - parent: true - childtemplate: - resources: - max: - vcore: 21 - memory: 610G - - name: notemplate - parent: true -``` -在这种情况下,`root.parent.sales`将直接使用parent队列`root.parent`的子模板。 -相比之下,`root.notemplate.sales`将使用在队列`root`上设置的子模板,因为其parent队列 `root.notemplate` 从队列`root`继承了子模板。 - -[已弃用] 如果您的集群依赖于动态叶队列可以从父级继承`application.sort.policy`的旧行为(由[YUNIKORN-195](https://issues.apache.org/jira/browse/YUNIKORN-195)引入),请迁移到模板。 -旧的行为将在未来的版本中被删除。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/resource_quota_mgmt.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/resource_quota_mgmt.md deleted file mode 100644 index 6d0811a3a36..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/resource_quota_mgmt.md +++ /dev/null @@ -1,336 +0,0 @@ ---- -id: resource_quota_management -title: 资源配额管理 ---- - - - -## 配额配置和规则 -与 Kubernetes 提供的简单命名空间资源配额相比,YuniKorn 可以提供一个更细化的资源配额管理设置。 - -在 Kubernetes 上,一个 pod 在提交时必须符合命名空间的配额。 -如果 pod 不适合命名空间配额, pod 就会被拒绝。 -客户端必须实现重试机制,如果它需要该 pod 被调度,就重新提交该 pod 。 - -与 Kubernetes 中的配额相反, YuniKorn 不在提交时强制执行配额,而只对主动消耗的资源执行配额。 -解释一下区别:当使用 YuniKorn 执行配额时,提交给 Kubernetes 的新 pod 总是被接受。 - Yunikorn 将对 pod 进行排队,而不将排队的 pod 的资源计入已消耗的配额。 -当 YuniKorn 试图调度 pod 时,它会在调度时检查 pod 是否符合为 pod 所分配的队列配置的配额。 -如果这时 pod 不符合配额, pod 就会被跳过,不计入资源消耗。 -这意味着,在一个 pod 的调度尝试成功之前,一个 pod 在 YuniKorn 配额系统中不消耗资源。 - -YuniKorn 中的资源配额与队列及其在队列层次结构中的位置有关。 -队列结构的基础,即 `root` 队列,不允许设置配额,因为它反映了集群的当前规模。 -节点的增加和删除会自动更新 `root` 队列的配额。 - -除了 `root` 队列,配额可以设置,并在层次结构的任何一点上执行。 -每个队列都可以有一个配额设置。配额在整个层次结构中是递归执行的。 -这意味着子队列使用的资源不能超过父队列的**配置的**配额。 -因此,在子队列上设置大于其父队列配额的配额不会有任何影响,并被作为配置错误处理。 - -在层次结构中,还有一些需要考虑的规则。 -如果一个父队列有多个子队列,所有子队列的**使用量之和不能超过父队列的**配置配额。 -然而,从配置的角度来看,这并不意味着所有子队的**配置的**配额之和必须小于父队的配额。 - -![队列定额](./../assets/queue-resource-quotas.png) - -举个例子,`root.parent` 队列的配额是 900。 -它包含三个子队列,其中两个有配额设置。 -`root.parent.child1` 没有设置配额,因此将被限制在 `root.parent` 的配额内。 -另外两个队列 `root.parent.child2` 和 `root.parent.child3` 各设置了 750 的配额。 -在正常运行期间,3 个子队列的总使用量将是 900。 -在每个子队列中运行的应用程序,每个都有超过 1000 的需求。 - -在这种情况下,分配可能是以下任何一种: -* 所有 900 个都被 `child1` 队列使用 -* 平均分布在 3 个队列中(每个队列 300 个)。 -* `child2` 最大使用 750,剩下的 150 由 `child3` 使用。 - -队列之间的确切分布将是波动的,取决于调度策略。 - -## 转换 Kubernetes 资源和配额 - -对pod的资源支持仅限于作为_需求_规范的一部分而指定的资源: - -* _cpu_ 被映射到 _vcore_,其值为 milli cpu。 -* _memory_ 被映射到 _memory_,其值为MB(1 MB = 10^6 B = 1 000 000 B)。 -* 所有其他资源都按照规定进行映射。 - -支持 [Kubernetes文档](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) 中提到的扩展资源。 - -有一个单一容器的 pod 例子: -```yaml -apiVersion: v1 -kind: Pod -spec: - containers: - - name: container-1 - resources: - requests: - cpu: "250m" - memory: "1Gi" - hugepages-1Gi: "1" -``` -上述规范将在 YuniKorn 中为调度设置 pod 资源请求: -* _vcore_ -> 250m -* _memory_ -> 1073741824 -* _hugepages-1Gi_ -> 1 - -两个备注: -多个容器规格将被自动汇总为一个总的 pod 资源请求。所有的内存都是以字节为单位报告的。 - -在为队列使用静态队列定义的情况下,对配额中可指定的资源类型没有限制。 -作为自动队列创建的一部分,命名空间上的配额注释被限制在相当于 _cpu_ 和 _memory_ 的资源。 -参见下面的 [设置](#Namespace-quota),了解命名空间上的配额注释。 - -## Kubernetes 和 YuniKorn 配额互动 -建议关闭而不是配置 Kubernetes 命名空间配额。 -只使用 YuniKorn 队列配额提供了一个更灵活的设置,并允许对工作负载进行排队。 - -在同时开启 YuniKorn 和 Kubernetes 配额的设置中,考虑以下几点: -* 需要维护两个独立的配置。 - 这增加了维护负担,以及配置错误的可能性。 -* 两个配额都会被强制执行。 - -开启这两个配额可能会导致意外的行为。 -主要问题是,Kubernetes 命名空间配额在提交时被强制执行。 -有三种配额配置的组合是可能的。 -当与 YuniKorn 配额结合使用时,这3种组合可能有两种效果。 - -1. 两种配额都是_平等的_:工作负载将不被排队,可以使用全部配置的配额。 - - 最大使用量和排队将被限制在设定的配额内 -2. Kubernetes 配额比 YuniKorn 低:YuniKorn 配额将永远不会达到,工作负载将不会被排队。 - - 最大使用量将被限制在 Kubernetes 的配额内。 -3. Kubernetes 配额比 YuniKorn 高: YuniKorn 将把使用量限制在 YuniKorn 中设置的配额。 - Kubernetes 配额将在提交时强制执行,从而为可以在 YuniKorn 配额之上排队的工作负载设置限制。 - - 最大使用量将被限制在 YuniKorn 的配额内。 - - 工作负载的排队将被限制在 Kubernetes 配额内。 - -:::note -下面的配置例子只是为了演示需要的格式 -来创建一个设置了配额的队列层次结构。 -::: - -## 静态队列定义 - -### 目标 -一个预先配置好的具有最大和保证容量的队列层次结构。 -用户只能向叶子队列提交申请。 -这种方法管理每个队列的资源容量,适用于队列不经常变化的情况。 - -### 配置 -将以下配置应用于 YuniKorn 的 configmap,以: -* 在 `root` 下设置 3 个队列 -* 每个队列都有一个特定的保证和最大容量 -* 任何人都可以向任何队列提交 - -```yaml -partitions: - - name: default - queues: - - name: root - submitacl: '*' - queues: - - name: advertisement - resources: - guaranteed: - memory: 500G - vcore: 50 - max: - memory: 800G - vcore: 80 - - name: search - resources: - guaranteed: - memory: 400G - vcore: 40 - max: - memory: 600G - vcore: 60 - - name: sandbox - resources: - guaranteed: - memory: 100G - vcore: 10 - max: - memory: 100G - vcore: 10 -``` - -### 运行一个工作负载 -为了在特定队列中运行应用程序,你需要在所有 pod 规格中设置以下标签。 -所有具有相同 `applicationID` 标签的 pod 被认为是一个应用程序。 -在下面的例子中,应用程序 `my-test-app` 将在队列 `root.sandbox` 中运行: - -```yaml -labels: - app: my-test-app - applicationId: "my-test-app-01" - queue: root.sandbox -``` - -## 名称空间到队列的映射 - -### 目标 -自动将Kubernetes的 `namespace` 映射到 YuniKorn 的队列。 -用户在 Kubernetes 中创建所需的命名空间。 -YuniKorn k8s shim 和核心调度器会自动传递所需信息,并将命名空间映射到队列中,如果队列不存在,则创建队列。 -资源配额将由 YuniKorn 管理,而不是使用 Kubernetes 命名空间配额。 -这确实需要按照下面的 [设置](#Namespace-quota) 设置命名空间,不需要 Kubernetes 配额的执行和标签。 - -### 配置 -将以下配置应用于 YuniKorn 的配置图: - -```yaml -partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*' - properties: - application.sort.policy: stateaware -``` - -该配置根据 `tag` 规则放置一个应用程序。 -选择的标签是 `namespace` 标签,它由 k8s shim 自动添加到所有被创建的应用程序中。 -`create` 标志被设置为 `true`,如果队列不存在,它将触发与命名空间同名的队列的创建。 - -自动创建的子队列中的应用程序将根据父队列上设置的排序策略进行排序。 -在这种情况下,属性 `application.sort.policy` 在此配置中被设置为 `stateaware` 。 -这是一个适用于批处理作业的简单应用排序策略,你可以找到更多的文件 [这里](sorting_policies.md#StateAwarePolicy)。 - -你可以在安装过程中使用 helm charts 来改变配置,通过覆盖在 -[helm chart template](https://github.com/apache/yunikorn-release/blob/master/helm-charts/yunikorn/values.yaml#L71-L81)。 - -### 命名空间配额 -Kubernetes 中的命名空间包含配额信息。 -如果在命名空间上设置了配额,Kubernetes 将自动执行该配额。 -在 YuniKorn 被用于执行配额的情况下,必须在命名空间上设置配额。 - -为了允许在命名空间上指定配额,应在命名空间对象中设置以下注释: - -```yaml -yunikorn.apache.org/namespace.quota: "{\"cpu\": \"64\", \"memory\": \"100G\", \"nvidia.com/gpu\": \"1\"}" -``` -YuniKorn 将解析这些注释,并设置映射到该命名空间的队列的最大容量。 -指定的值遵循标准的 Kubernetes 格式和单位规范。 -注释值必须是一个符合 json 的字符串。确保双引号被正确转义,以免造成任何问题。 - -上面的例子将把映射到注释命名空间的队列限制在 64 个 CPU、100GB 内存和 1 个 `nvidia.com/gpu`。 - -[已废弃] -以下注释已被废弃,并将在下一个主要版本中被删除。 -它们只支持映射内存和cpu,不支持其他资源类型。 -```yaml -yunikorn.apache.org/namespace.max.cpu: "64" -yunikorn.apache.org/namespace.max.memory: "100Gi" -``` -废弃注释的例子将把队列配额设置为 64 个 CPU 和 100GB 内存。 - -### 运行一个工作负载 - -应用程序,以及作为应用程序一部分的 pod,可以在没有特定标签的情况下提交。 -YuniKorn 将自动添加所需的标签。 -如果需要,配置的放置规则将创建队列,并将应用程序添加到队列中。 - -例如,如果一个应用程序被提交到命名空间 `development` ,那么该应用程序将在 `root.development` 队列中运行。 - -## 命名空间的父队列映射 - -### 目标 -尽管使用 `namespace` 标签的标签放置规则能够将应用程序放置在队列中,但这在所有设置中可能是不够的。 -在某些情况下,例如多租户,命名空间需要被归为一组。 -管理员可以对命名空间进行注释,如果设置了放置规则,可以根据多个注释动态放置应用程序。 -YuniKorn 不能也不会将一个命名空间的所有注解添加到一个应用程序。 - -为了帮助支持这种分组情况,可以在命名空间上标记一个父队列。 - -### 配置 -这个功能的配置由两部分组成: -1. 映射规则 -1. 命名空间注释 - -首先,我们在 YuniKorn 的 configmap 上设置以下配置: - -```yaml -partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - parent: - name: tag - value: namespace.parentqueue - queues: - - name: root - queues: - - name: production - parent: true - - name: development - parent: true -``` - -用于命名空间到队列映射的配置与 [上文](#名称空间到队列的映射) 相同。 -作为放置规则的扩展,添加了一个 `parent` 规则以支持分组。 -父级规则用于生成层次结构中的父级,或上面的队列。 -该规则使用应用程序中的标签 `namespace.parentqueue` 来生成父队列名称。 -`namespace.parentqueue` 标签由 Kubernetes shim 自动添加,但确实需要一个命名空间注释(见下文)。 - -在给出的规则配置示例中,`create` 标志没有在父规则上设置。 -这意味着父队列必须存在于配置中,否则应用提交将失败。 -对于这个例子的配置,这意味着父队的支持值被限制为 `production` 和 `development`。 - -不能使用任何这些映射在父队列上设置配额。 -根据前面提供的命名空间映射,与命名空间相关的配额设置在命名空间队列上,而不是父队。 - -父队列的配额必须总是直接在配置中设置。 -这需要在父规则上将 `create` 标志设置为 `false`。 - -### 命名空间父队列 -与命名空间名称本身相反,并与配额设置相一致,命名空间需要被注解以使用父队列映射。 -命名空间名称在 Kubernetes 中必须是唯一的,这不受此注释的影响。 -相同的注解值可以用于多个命名空间: -```yaml -yunikorn.apache.org/parentqueue: root.production -``` - -上面的例子注释将把父队列映射到现有的 `root.production` 队列。 -注意,如果需要的话,规则将完全限定名称,因此你可以省略注释中的 `root.` 部分。 -如果注释以 `root.` 开头,系统会认为这是一个完全合格的队列名称。 - -为了使图片更完整,这里有一张图片,显示了 YuniKorn 中从 Kubernetes 命名空间到队列的映射。 -它使用了 Kubernetes 中命名空间的注释,以及映射规则的配置示例。 -`finance` 和 `sales`命名空间成为队列,归入父队列 `production` 之下。 -命名空间 `dev` 和 `test` 被放在 `development` 父队列下。 - -![队列配额](./../assets/namespace-mapping.png) - -### 运行一个工作负载 -应用程序,以及作为应用程序一部分的 pod,可以在没有特定标签或更改的情况下提交。 -YuniKorn 将添加标签,安置规则将做其余的事情。 -配置的放置规则将创建队列(如果需要),并将应用程序添加到队列中。 - -由于命名空间 `finance` 被注释为示例值,并且规则已经到位。 -`finance` 命名空间的应用程序将在动态创建的 `root.production.finance` 队列中运行。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/service_config.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/service_config.md deleted file mode 100644 index 362c1af7462..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/service_config.md +++ /dev/null @@ -1,792 +0,0 @@ ---- -id: service_config -title: 服务配置 ---- - - - -YuniKorn的官方版本是通过Helm charts部署到Kubernetes中的。YuniKorn的配置分为两部分:Helm配置和YuniKorn服务配置。 - -## Helm 配置 -Helm配置是用于将YuniKorn部署到Kubernetes的选项。 - -可以在YuniKorn安装期间通过Helm进行以下设置配置,可以使用Helm的命令行方式,例如`--set key=value`,也可以使用外部文件方式:`-f file.yaml`。以下示例将以YAML语法表示。 - -### 容器镜像 -YuniKorn以一组容器镜像的形式提供。可以按照以下方式自定义其位置和拉取策略: - - # 标准调度器的镜像信息 - image: - repository: apache/yunikorn - tag: scheduler-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - - # 插件调度器的镜像信息 - pluginImage: - repository: apache/yunikorn - tag: scheduler-plugin-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - - # Web UI的镜像信息 - web: - image: - repository: apache/yunikorn - tag: web-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - - # 准入控制器的镜像信息 - admissionController: - image: - repository: apache/yunikorn - tag: admission-1.2.0 # 默认取决于YuniKorn版本 - pullPolicy: Always - -### Kubernetes 配置 - -#### affinity -设置YuniKorn调度器Pod的亲和性。 - -默认值: `{}` - -示例: - - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: - - primary1 - - primary2 - -#### admissionController.affinity -设置YuniKorn准入控制器Pod的亲和性。 - -默认值: `{}` - -示例: - - admissionController: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: - - primary1 - - primary2 - -#### hostNetwork -控制调度器是否应在主机网络中运行。 - -默认值: `false` - -示例: - - hostNetwork: true - -#### admissionController.hostNetwork -控制准入控制器是否应在主机网络中运行。 - -默认值: `true` - -示例: - - admissionController: - hostNetwork: false - -#### imagePullSecrets -提供提取YuniKorn镜像所需的secret。 - -默认值: `[]` - -示例: - - imagePullSecrets: - - secret1 - - secret2 - -#### nodeSelector -设置用于放置YuniKorn调度器Pod的节点选择算符。 - -默认值: `{}` - -示例: - - nodeSelector: - role.node.kubernetes.io/infra: "true" - -#### admissionController.nodeSelector -设置用于放置YuniKorn准入控制器Pod的节点选择算符。 - -默认值: `{}` - -示例: - - admissionController: - nodeSelector: - role.node.kubernetes.io/infra: "true" - -#### admissionController.replicaCount -设置用于YuniKorn准入控制器的副本数。可以将其设置为大于1以实现高可用性。 - -默认值: `1` - -示例: - - admissionController: - replicaCount: 2 - -#### serviceAccount -为YuniKorn调度器设置备用服务账户。 - -不建议更改此值,因为Helm会为默认用户安装基于角色的访问控制(RBAC)策略,而这对于正确的功能是必需的。 - -默认值: `yunikorn-admin` - -示例: - - serviceAccount: my-account - -#### admissionController.serviceAccount -为YuniKorn准入控制器设置备用服务账户。 - -不建议更改此值,因为Helm会为默认用户安装基于角色的访问控制(RBAC)策略,而这对于正确的功能是必需的。 - -默认值: `yunikorn-admission-controller` - -示例: - - admissionController: - serviceAccount: my-account - -#### service.type -设置用于调度器的服务类型。 - -默认值: `ClusterIP` - -示例: - - service: - type: ClusterIP - -#### admissionController.service.type -设置用于准入控制器的服务类型。 - -默认值: `ClusterIP` - -示例: - - admissionController: - service: - type: ClusterIP - -#### service.port -设置在YuniKorn调度器服务中用于REST API的暴露端口。不建议更改此值。 - -默认值: 9080 - -示例: - - service: - port: 9080 - -#### service.portWeb -设置在YuniKorn调度器服务中用于Web UI的暴露端口。不建议更改此值。 - -默认值: 9889 - -示例: - - service: - portWeb: 9889 - -#### tolerations -设置用于YuniKorn调度器Pod的容忍规则。 - -默认值: `[]` - -示例: - - tolerations: - - key: *infraRoleKey - operator: Equal - value: "true" - effect: NoSchedule - - key: CriticalAddonsOnly - operator: Exists - -#### admissionController.tolerations -设置用于YuniKorn准入控制器Pod的容忍规则。 - -默认值: `[]` - -示例: - - admissionController: - tolerations: - - key: *infraRoleKey - operator: Equal - value: "true" - effect: NoSchedule - - key: CriticalAddonsOnly - operator: Exists - -### 资源利用率 -可以按照以下方式自定义YuniKorn Pod所需的资源: - - # 调度器容器的资源 - resources: - requests: - cpu: 200m - memory: 1Gi - limits: - cpu: 4 - memory: 2Gi - - # Web UI容器的资源 - web: - resources: - requests: - cpu: 100m - memory: 100Mi - limits: - cpu: 100m - memory: 500Mi - - # 准入控制器的资源 - admissionController: - resources: - requests: - cpu: 100m - memory: 500Mi - limits: - cpu: 500m - memory: 500mi - -### 自选功能 - -#### embedAdmissionController -控制是否启用YuniKorn准入控制器。 - -默认值: `true` - -示例: - - embedAdmissionController: false - -#### enableSchedulerPlugin -控制是否以调度器插件模式运行YuniKorn。 - -默认值: `false` - -示例: - - enableSchedulerPlugin: true - -### YuniKorn 默认值 - -#### yunikornDefaults -设置将呈现到 `yunikorn-defaults` ConfigMap的条目。这可以用于在部署时预配置YuniKorn。可以在此处设置 [YuniKorn 配置](#yunikorn-配置) 中声明的任何设置。 - -默认值: `{}` - -示例: - - yunikornDefaults: - service.clusterId: yunikorn-01 - service.policyGroup: group-01 - group-01.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - - -### 弃用设置 -以下设置已被弃用,或在将来的 YuniKorn 版本中被删除。现在应该在 `yunikorn-configs` ConfigMap 或通过 Helm 的 `yunikornDefaults` 部分指定: - -| 弃用设置 | ConfigMap 替代方案 | -| --------------------------------------- | ----------------------------------------------- | -| operatorPlugins | service.operatorPlugins | -| placeHolderImage | service.placeholderImage | -| admissionController: processNamespaces | admissionController.filtering.processNamespaces | -| admissionController: bypassNamespaces | admissionController.filtering.bypassNamespaces | -| admissionController: labelNamespaces | admissionController.filtering.labelNamespaces | -| admissionController: noLabelNamespaces | admissionController.filtering.noLabelNamespaces | -| configuration | queues.yaml | - -以下是一個過時的例子: - - operatorPlugins: general - placeHolderImage: registry.k8s.io/pause:3.7 - admissionController: - processNamespaces: "^spark-,^mpi-" - bypassNamespaces: "^kube-system$" - labelNamespaces: "^spark-" - noLabelNamespaces: "^mpi-legacy-" - configuration: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -以下是替代示例: - - yunikornDefaults: - service.policyGroup: queues - service.operatorPlugins: general - service.placeholderImage: registry.k8s.io/pause:3.7 - admissionController.processNamespaces: "^spark-,^mpi-" - admissionController.bypassNamespaces: "^kube-system$" - admissionController.labelNamespaces: "^spark-" - admissionController.noLabelNamespaces: "^mpi-legacy-" - queues.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -近期,如果同时指定了被弃用的参数和替代的ConfigMap条目,则ConfigMap条目将优先生效。 - - -## YuniKorn 配置 - -YuniKorn的服务配置由两个 Kubernetes ConfigMaps 控制,它们分别是在安装 YuniKorn 的命名空间中:`yunikorn-defaults` 和 `yunikorn-configs`。 - -运行时,YuniKorn会轮询这些ConfigMaps并将它们合并以形成有效配置。如果在两个 ConfigMaps 中都存在某个设置,则 `yunikorn-configs` 中的设置将覆盖 `yunikorn-defaults` 中的设置。 - -`yunikorn-defaults` 的目的是提供一种机制,供 Helm 配置初始的服务配置细节。它不应该被直接修改。 - -`yunikorn-configs` ConfigMap 完全不受 Helm 管理,适用于可能随时间变化的配置,如队列配置。所有对 YuniKorn 配置的更改都应在此处进行,而不是在基础设施供应之外。 - -### 默认 ConfigMap - -如果没有提供任何配置映射,或者某个选项未被指定,YuniKorn将使用此处列出的默认值: - - apiVersion: v1 - kind: ConfigMap - metadata: - name: yunikorn-configs - data: - service.clusterId: "mycluster" - service.policyGroup: "queues" - service.schedulingInterval: "1s" - service.volumeBindTimeout: "10s" - service.eventChannelCapacity: "1048576" - service.dispatchTimeout: "5m" - service.operatorPlugins: "general" - service.disableGangScheduling: "false" - service.enableConfigHotRefresh: "true" - service.placeholderImage: "registry.k8s.io/pause:3.7" - service.instanceTypeNodeLabelKey: "node.kubernetes.io/instance-type" - health.checkInterval: "30s" - log.level: "0" - kubernetes.qps: "1000" - kubernetes.burst: "1000" - admissionController.webHook.amServiceName: "yunikorn-admission-controller-service" - admissionController.webHook.schedulerServiceAddress: "yunikorn-service:9080" - admissionController.filtering.processNamespaces: "" - admissionController.filtering.bypassNamespaces: "^kube-system$" - admissionController.filtering.labelNamespaces: "" - admissionController.filtering.noLabelNamespaces: "" - admissionController.accessControl.bypassAuth: "false" - admissionController.accessControl.trustControllers: "true" - admissionController.accessControl.systemUsers: "^system:serviceaccount:kube-system:" - admissionController.accessControl.externalUsers: "" - admissionController.accessControl.externalGroups: "" - queues.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -### 服务设置 -YuniKorn可理解以下参数: - -#### service.clusterId -为正在配置的集群设置标识符。这将作为REST API调用的一部分返回。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `mycluster` - -示例: - - service.clusterId: "yunikorn-east" - -#### service.policyGroup -定义此调度器使用的策略组。策略组用于选择多个队列配置之一。此设置的值加上`.yaml`的扩展名控制用于检索分区和队列配置的ConfigMap条目。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `queues` - -示例: - - service.policyGroup: group_b - group_b.yaml: | - partitions: - - name: default - placementrules: - - name: tag - value: namespace - create: true - queues: - - name: root - submitacl: '*'` - -#### service.schedulingInterval -控制YuniKorn执行调度运行的频率。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `1s` - -示例: - - service.schedulingInterval: "5s" - -#### service.volumeBindTimeout -控制卷绑定失败的超时时间。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `10s` - -示例: - - service.volumeBindTimeout: "30s" - -#### service.eventChannelCapacity -控制YuniKorn一次允许有多少个内部调度事件在运行。作為内存不足的保护。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `1048576` - -示例: - - service.eventChannelCapacity: "1000000" - -#### service.dispatchTimeout -控制如果事件通道已满,内部事件将重新尝试调度多长时间。如果超过此超时时间,将发出警告。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `5m` - -示例: - - service.dispatchTimeout: "10m" - -#### service.operatorPlugins -控制在YuniKorn中启用的运算符插件集。目前只实现了 `general`,`spark-k8s-operator` 和 `yunikorn-app` 插件。`general` 插件不应禁用。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `general` - -示例: - - service.operatorPlugins: "general,spark-k8s-operator" - -#### service.disableGangScheduling -允许全局禁用gang调度功能(不建议)。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `false` - -示例: - - service.disableGangScheduling: "true" - -#### service.enableConfigHotRefresh -控制配置是否应该进行热重载。默认情况下,这个设置为 `true`,但是它可以被禁用,以避免 ConfigMaps 的更改被拾起直到调度器重启。 - -更改此设置将在YuniKorn不需要重启的情况下生效。 - -注意:如果禁用了此设置,则可能无法重新启用,除非重新启动YuniKorn。 - -默认值: `true` - -示例: - - service.enableConfigHotRefresh: "false" - -#### service.placeholderImage -设置将用于gang调度占位符的Pod镜像。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `registry.k8s.io/pause:3.7` - -示例: - - service.placeholderImage: "registry.k8s.io/pause:3.6" - -#### service.instanceTypeNodeLabelKey -设置节点标签的键,该键用于标识节点的实例类型。如果设置了此值,则YuniKorn将使用此标签来区分节点的实例类型。 - -更改此设置需要重新启动YuniKorn才能生效。 - -默认值: `node.kubernetes.io/instance-type` - -示例: - - service.instanceTypeNodeLabelKey: "node.kubernetes.io/my-instance-type" - -### 健康检查设置 - -#### health.checkInterval -设置YuniKorn自动健康检查的时间间隔。 - -将该值设置为 `0` 或负值将禁用后台健康检查。 - -更改此设置不需要重新启动YuniKorn即可生效。 - -默认值: `30s` - -示例: - - health.checkInterval: "1m" - -### 日志设置 - -#### log.level -设置YuniKorn的日志详细程度。 - -更改此设置不需要重新启动YuniKorn即可生效。可用的值有: - - - `-1`: 调试(Debug) - - `0`: 信息(Info) - - `1`: 警告(Warn) - - `2`: 错误(Error) - - `3`: 不可恢復的錯誤(DPanic) - - `4`: 不可恢復的錯誤(Panic) - - `5`: 致命错误(Fatal) - -默认值: `0` (Info) - -示例: - - log.level: "-1" - -### Kubernetes 设置 - -#### kubernetes.qps -设置 YuniKorn Kubernetes 客户端每秒查询(QPS)的数量。该数字必须>=0。 - -更改此设置需要重新启动 YuniKorn 才能生效。 - -默认值: `1000` - -示例: - - kubernetes.qps: "500" - -#### kubernetes.burst -该设置用于设置 Kubernetes 查询的突发大小,临时允许事件突发到此数字,而不会超过 kubernetes.qps。 - -更改此设置需要重新启动 YuniKorn 才能生效。 - -默认值: `1000` - -示例: - - kubernetes.burst: "500" - -### 准入控制器 webhook 设置 - -#### admissionController.webHook.amServiceName -设置 YuniKorn 准入控制器所在的服务的名称下注册。这是准入控制器注册所必需的本身与 Kubernetes 兼容,通常不应更改。 - -更改此设置需要重新启动 YuniKorn 准入控制器生效。 - -默认值: `yunikorn-admission-controller-service` - -示例: - - admissionController.webHook.amServiceName: "yunikorn-admission-controller-alt-service-name" - -#### admissionController.webHook.schedulerServiceAddress -设置 YuniKorn 调度器服务的地址。这个地址必须是准入控制器可达,并由准入使用验证 ConfigMap 更改时的控制器。准入控制器将联系调度器上的 REST API 以验证任何提议 ConfigMap 更改。通常不应更改此设置。 - -更改此设置需要重新启动 YuniKorn 准入控制器生效。 - -默认值: `yunikorn-service:9080` - -示例: - - admissionController.webHook.schedulerServiceAddress: "alt-yunikorn-service:9080" - -### 准入控制器过滤设置 - -#### admissionController.filtering.processNamespaces -控制哪些命名空间会将 pod 转发给 YuniKorn 进行调度。 - -此设置是以逗号分隔的正则表达式列表。如果这个设置是一个空字符串,在所有命名空间中创建的 pod 将由 YuniKorn 调度。 - -无需重新启动准入控制器即可获取对此设置的更改。 - -默认值: empty - -示例: - - # YuniKorn 仅在 spark-* 和 mpi-* 命名空间中调度 pod - admissionController.filtering.processNamespaces: "^spark-,^mpi-" - -#### admissionController.filtering.bypassNamespaces -该设置控制哪些命名空间的 pod *不会* 被转发到 YuniKorn 进行调度。它作为 `admissionController.filtering.processNamespaces` 的例外列表。 - -此设置是一组逗号分隔的正则表达式。如果该设置为空字符串,则不会从任何命名空间中排除由 YuniKorn 处理的 pod。 - -默认情况下,该设置将排除 kube-system 命名空间中的 pod,因为这些 pod 的调度通常需要成功将节点添加到群集中。这可能会阻止 YuniKorn 本身或其他关键服务的启动。 - -更改此设置将被 admission controller 感知,无需重新启动。 - -默认值: `^kube-system$` - -示例: - - # 不要在 kube-system 或 fluentd-* 命名空间中调度 pod。 - admissionController.filtering.bypassNamespaces: "^kube-system$,^fluentd-" - -#### admissionController.filtering.labelNamespaces -该设置控制哪些命名空间的 pod 将被打上 `applicationId` 标签。默认情况下,所有由 YuniKorn 调度的 pod 都会被打上 `applicationId` 标签。 - -当使用标准部署模型运行 YuniKorn 时,所有 pod 都应打上标签,因为 YuniKorn 无法调度未定义 `applicationId` 的 pod。 - -当使用调度器插件部署模型运行 YuniKorn 时,此设置可用于过滤哪些命名空间应通过 YuniKorn 的队列模型进行调度,哪些命名空间应绕过队列模型并由嵌入式默认调度器进行调度。 - -此设置是一组逗号分隔的正则表达式。如果该设置为空字符串,则将为转发到 YuniKorn 的所有 pod 打上 `applicationId` 标签。 - -更改此设置将被 admission controller 感知,无需重新启动。 - -默认值: empty - -示例: - - # 将 applicationId 标签添加到 spark-* 命名空间中的 pod。 - admissionController.filtering.labelNamespaces: "^spark-" - -#### admissionController.filtering.noLabelNamespaces -该设置控制哪些命名空间的 pod *不会* 打上` applicationId` 标签。它作为 `admissionController.filtering.labelNamespaces` 的例外列表。 - -当使用标准部署模型运行 YuniKorn 时,所有 pod 都应打上标签,因为 YuniKorn 无法调度未定义 `applicationId` 的 pod。 - -当使用调度器插件部署模型运行 YuniKorn 时,此设置可用于过滤哪些命名空间应通过 YuniKorn 的队列模型进行调度,哪些命名空间应绕过队列模型并由嵌入式默认调度器进行调度。 - -此设置是一组逗号分隔的正则表达式。如果该设置为空字符串,则不会应用到 `admissionController.filtering.labelNamespaces` 的任何例外。 - -更改此设置将被 admission controller 感知,无需重新启动。 - -默认值: empty - -示例: - - # 在命名空间为 noqueue 时跳过队列。 - admissionController.filtering.labelNamespaces: "^noqueue$" - -### 准入控制器访问控制列表(ACL)设置 - -#### admissionController.accessControl.bypassAuth -允许外部用户创建带有用户信息的 pod。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: `false` - -示例: - - admissionController.accessControl.bypassAuth: "true" - -#### admissionController.accessControl.trustControllers -允许控制器用户创建带有用户信息的 pod。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: `true` - -示例: - - admissionController.accessControl.trustControllers: "false" - -#### admissionController.accessControl.systemUsers -逗号分隔的正则表达式列表,用于匹配允许的控制器服务账户。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: `^system:serviceaccount:kube-system:` - -示例: - - # 允许所有的 kube-system 账户以及 kube-controller-manager - admissionController.accessControl.systemUsers: "^system:serviceaccount:kube-system,^system:kube-controller-manager$" - -#### admissionController.accessControl.externalUsers -逗号分隔的正则表达式列表,用于匹配允许的外部用户。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: empty - -示例: - - # 允许 'alice'、'bob' 和 'admin-*' - admissionController.accessControl.externalUsers: "^alice$,^bob$,^admin-" - -#### admissionController.accessControl.externalGroups -逗号分隔的正则表达式列表,用于匹配允许的外部用户组。 - -更改此设置将被准入控制器感知,无需重新启动。 - -默认值: empty - -示例: - - # 允许 'sales'、'marketing' 和 'admin-*' - admissionController.accessControl.externalGroups: "^sales$,^marketing$,^admin-" - diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/sorting_policies.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/sorting_policies.md deleted file mode 100644 index 49d64e9002d..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/sorting_policies.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -id: sorting_policies -title: 排序策略 ---- - - - -调度器使用策略可以在不更改代码的情况下改变调度行为。 -可以为以下项目设置策略: -* [应用程序](#应用程序排序) -* [节点](#节点排序) -* [请求](#请求排序) - -## 应用程序排序 -通过配置为每个队列设置应用程序排序策略。排序策略设置仅对*叶子*队列有效。每个*叶子*队列可以使用不同的策略。 - -排序策略仅指定应用程序在队列内排序的顺序。 -该顺序对于指定在分配资源时首先考虑哪个应用程序非常重要。 -排序策略*不会*影响在队列中同时调度或激活的应用程序数量。 -所有具有待处理资源请求的应用程序都可以并且将在队列中调度,除非明确地被过滤掉。 -即使使用先进先出策略(FIFO)对应用程序进行排序,多个应用程序也将在队列中并行运行。 - -*父*队列始终使用公平策略对子队列进行排序。 - -考虑子队列的相对优先级(在*父*队列排序的情况下)和应用程序的相对优先级(在*叶子*队列排序的情况下)。 -要在调度时忽略应用程序和队列优先级,请将队列属性`application.sort.priority`设置为`disabled`。 - -以下配置条目将应用程序排序策略设置为FIFO,适用于队列`root.sandbox`: - -```yaml -partitions: - - name: default - queues: - - name: root - queues: - - name: sandbox - properties: - application.sort.policy: fifo -``` - -仅考虑具有未处理请求的应用程序进行调度。 -在排序应用程序*时*应用筛选器以移除所有没有未处理请求的应用程序。 - -### FifoSortPolicy -简短描述:先进先出,基于应用程序创建时间。 - -配置值:`fifo`(默认) - -在排序之前,需要过滤应用程序,并且必须有挂起(pending)的资源请求。 - -经过筛选后,应用程序将根据创建时间戳进行排序,不会使用其他过滤。 -由于系统仅在锁定状态下添加应用程序,因此不可能有两个具有完全相同时间戳的应用程序。 - -结果,最早的请求资源的应用程序获得资源。 -较晚请求的应用程序将在满足之前应用程序当前所有请求之后获得资源。 - -### FairSortPolicy -简短描述:基于资源利用率公平性排序。 - -配置值: `fair` - -在排序之前,需要过滤应用程序,并且必须有挂起(pending)的资源请求。 - -经过筛选后,剩下的应用程序将根据使用情况进行排序。 -应用程序的使用情况是指应用程序所有已确认和未确认的分配。 -计算使用情况时,将考虑应用程序中定义的所有资源。 - -达到的效果是资源相对平均分配给所有请求资源的应用程序 - -### StateAwarePolicy -简短描述:限制同一时间只有一个为 Starting 或 Accepted 状态的应用程序。 - -配置值: `stateaware` - -此排序策略需要了解应用程序状态。 -应用程序状态在[应用程序状态](design/scheduler_object_states.md#application-state)文档中进行了描述。 - -在对所有排队的应用程序进行排序之前,将应用以下过滤器: -第一个过滤器基于应用程序状态。 -以下应用程序通过过滤器并生成第一个中间列表: -* 处于 *running* 状态的所有应用程序 -* *一个*(1)处于 *starting* 状态的应用程序 -* 如果*没有*处于 *starting* 状态的应用程序,则添加 *一个*(1)处于 *accepted* 状态的应用程序 - -第二个过滤器将第一个过滤器的结果作为输入。 -再次过滤初步列表:删除所有*没有*挂起(pending)请求的应用程序。 - -根据状态和挂起(pending)请求进行过滤后,剩余的应用程序将进行排序。 -因此,最终列表将使用剩余的应用程序两次过滤并按创建时间排序。 - -回顾下 *Starting* 和 *Accepted* 状态的交互: -只有在没有处于 *Starting* 状态的应用程序时,才会添加处于 *Accepted* 状态的应用程序。 -处于 *Starting* 状态的应用程序不必有挂起(pending)请求。 -任何处于 *Starting* 状态的应用程序都将防止 *Accepted* 应用程序被添加到已过滤的列表中。 - -有关详细信息,请参阅设计文档中的 [示例](design/state_aware_scheduling.md#example-run) 运行。 - -达到的效果是,已经在运行的应用程序讲优先得到资源。 -在所有已运行的应用程序后,逐一调度新的应用程序。 - - -## 节点排序 -节点排序策略通过配置文件为每个分区设置,不同的分区可以使用不同的策略。 -以下配置项将分区`default`的节点排序策略设置为`fair`: -```yaml -partitions: - - name: default - nodesortpolicy: - type: fair -``` - -### FairnessPolicy -简要描述:按可用资源排序,按降序排列 - -配置值:`fair` (默认值) - -行为: -按可用资源的数量对节点列表进行排序,使具有最高可用资源量的节点排在列表的第一位。 -计算使用情况时,将考虑节点上定义的所有资源。 -对于节点的相同类型资源进行比较。 - -这将导致考虑可用性最低的节点首先进行新分配的分配,从而在所有可用节点上分散分配。 -这将导致每个可用节点的整体利用率降低,除非整个环境的利用率非常高。 -将所有节点的负载保持在相似水平有助于。 -在自动缩放添加新节点的环境中,这可能会触发意外的自动缩放请求。 - -### BinPackingPolicy -简要描述:按可用资源排序,按升序排列 - -配置值:`binpacking` - -行为: -按可用资源的数量对节点列表进行排序,使具有最低可用资源量的节点排在列表的第一位。 -计算使用情况时,将考虑节点上定义的所有资源。 -对于节点的相同类型资源进行比较。 - -这将导致考虑可用性最高的节点首先进行新分配的分配,从而使少量节点的利用率更高,更适合云部署。 - -## 资源加权 -节点排序策略可能使用节点利用率来确定顺序。 -因为节点可以具有多个唯一的资源类型,所以节点的利用率是由其各个资源类型的加权平均值确定的。 -资源加权可以通过使用`nodesortpolicy`的`resourceweights`部分进行自定义。 -如果`resourceweights`不存在或为空,则默认配置将`vcore`和`memory`的权重设置为相等的`1.0`。 -所有其他资源类型都将被忽略。 -只有明确提到的资源类型才会具有权重。 - -YuniKorn在内部跟踪CPU资源作为`vcore`资源类型。 -这将映射到Kubernetes资源类型`cpu`。 -除`vcore`和memory之外,所有其他资源类型在YuniKorn和Kubernetes之间具有一致的命名。 - -例如,在默认配置中,如果节点的CPU和内存分别分配了`90%`和`50%`,则该节点将被视为已使用`70%`。 - -以下配置条目为分区default设置了`vcore`权重为`4.0`和`memory`权重为`1.0`。 -这将使CPU使用的权重比内存使用高四倍: -```yaml -partitions: - - name: default - nodesortpolicy: - type: fair - resourceweights: - vcore: 4.0 - memory: 1.0 -``` - -使用此配置,在此示例中,如果节点的CPU和内存分别分配了`90%`和`50%`,则该节点将被视为已使用`82%`。 - -请注意,权重是相对于彼此的,因此指定`{4.0,1.0}`的权重等效于`{1.0,0.25}`。不允许负权重。 - -## 请求排序 -当前仅有一种策略可用于在应用程序内对请求进行排序。 -此策略不可配置。 -仅可以基于请求的优先级对请求进行排序。 -如果应用程序中有多个具有相同优先级的请求,则请求的顺序未确定。 -这意味着具有相同优先级的请求的顺序可能会在运行之间改变。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/troubleshooting.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/troubleshooting.md deleted file mode 100644 index 4b47d6b0ab4..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/troubleshooting.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -id: troubleshooting -title: 故障排除 ---- - - - -## 调度日志(Scheduler logs) - -### 检索调度日志 - -调度器会将日志写入stdout/stderr,docker容器就会将这些日志重新导向到节点的本地位置,你可以从[这里](https://docs.docker.com/config/containers/logging/configure/)读到更多的文档,这些日志可以通过[kuberctl logs](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs)检索。如: - -```shell script -//获取调度的pod -kubectl get pod -l component=yunikorn-scheduler -n yunikorn -NAME READY STATUS RESTARTS AGE -yunikorn-scheduler-766d7d6cdd-44b82 2/2 Running 0 33h - -//检索日志 -kubectl logs yunikorn-scheduler-766d7d6cdd-44b82 yunikorn-scheduler-k8s -n yunikorn -``` - -在大多数的情况下,这个命令没有办法获取所有的日志,因为调度程序的日志数量庞大,您需要设置[集群级别的日志收集](https://kubernetes.io/docs/concepts/cluster-administration/logging/#cluster-level-logging-architectures)。推荐的设置方式是利用[fluentd](https://www.fluentd.org/)在外部储存(例如s3)上持久的收集日志。 - -### 设定日志级别 - -### -:::note -我们建议通过REST API来调整日志级别,如此以来我们不需要每次修改级别时重新启动调动程序的pod。但是透过编辑部署配置来设定日志级别时,需要重新启用调度程序的pod,因此强烈不建议这么做。 -::: - -停止调度器: -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -``` - -使用vim编辑部署配置: -```shell script -kubectl edit deployment yunikorn-scheduler -n yunikorn -``` - -在容器模板的`env`字段中加入`LOG_LEVEL`。例如将`LOG_LEVEL`设置为0会将日志纪录的级别设置为`INFO`。 - -```yaml -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: -… -spec: -template: -… -spec: -containers: -- env: -- name: LOG_LEVEL -value: '0' -``` - -启用调度器: -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -可使用的日志级别: - -| 值 | 日志级别 | -|:-----: |:-------------: | -| -1 | DEBUG | -| 0 | INFO | -| 1 | WARN | -| 2 | ERROR | -| 3 | DPanic | -| 4 | Panic | -| 5 | Fatal | - -## Pods卡在`Pending`状态 - -如果Pod卡在Pending状态,则意味着调度程序找不到分配Pod的节点。造成这种情况有以下几种可能: - -### 1.没有节点满足pod的放置要求 - -可以在Pod中配置一些放置限制,例如[节点选择器(node-selector)](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)、[亲合/反亲合性(affinity/anti-affinity)](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)、对节点的[污点(taints)](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)没有一定的容忍度等。若要修正此类问题,你可以通过以下方法观察pod: - -```shell script -kubectl describe pod -n <命名空间> -``` - -pod事件中包含预测失败,而这解释了为什么节点不符合分配条件 - -### 2.队列的可用资源不足 - -如果队列的可用资源不足,Pod将等待队列资源。检查队列是否还有空间可以给Pending pod的方法有以下几种: - -1 ) 从Yunikorn UI检查队列使用情况 - -如果你不知道如何访问UI,可以参考[这里](../get_started/get_started.md#访问-web-ui)的文档。在`Queues`页面中,寻找Pod对应到的队列。你将能够看到队列中剩馀的可用资源。 - -2 ) 检查pod事件 - -运行`kubectl describe pod`以获取pod事件。如果你看到类似以下的事件:`Application does not fit into <队列路径> queue`。则代表pod无法分配,因为队列的资源用完了。 - -当队列中的其他Pod完成工作或被删除时,代表目前Pending的pod能得到分配,如果Pod依旧在有足够的剩馀资源下,保持pending状态,则可能是因为他正在等待集群扩展。 - -## 获取完整的状态 - -Yunikorn状态储存中,包含了对每个进程中每个对象的状态。透过端点来检索,我们可以有很多有用的信息,举一个故障排除的例子:分区列表、应用程序列表(包括正在运行的、已完成的以及历史应用程序的详细信息)、节点数量、节点利用率、通用集群信息、集群利用率的详细信息、容器历史纪录和队列信息。 - -状态是Yunikorn提供的用于故障排除的宝贵资源。 - -有几种方法可以获得完整的状态: -### 1.调度器URL - -步骤: -*在浏览器中打开Yunikorn UI,且在URL中编辑: -*将`/#/dashboard`取代为`/ws/v1/fullstatedump`,(例如,`http://localhost:9889/ws/v1/fullstatedump`) -*按下回车键。 - -透过这个简单的方法来观看即时且完整的状态。 - -### 2.调度器的REST API - -使用以下的调度器REST API,能够让我们看到Yunikorn的完整状态。 - -`curl -X 'GET'http://localhost:9889/ws/v1/fullstatedump-H 'accept: application/json'` - -有关储存状态的更多信息,可以参阅[检索完整状态](api/scheduler.md#retrieve-full-state-dump)的文档。 - -## 重启调度器 -:::note -最好的故障排除方法是─把「重启调度器」当作完全没有其他方法之下的最后一步,他不应该在搜集所有日志和状态之前使用。 -::: - -Yunikorn可以在重启之后恢复其状态。Yunikorn调度器的pod作为deployment部署。我们可以透过`scale`来增加和减少副本数量来重启Yunikorn调度器,方法如下: - -```shell script -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=0 -kubectl scale deployment yunikorn-scheduler -n yunikorn --replicas=1 -``` - -## 成组调度 -### 1.没有占位符被创建,且app处于pending状态 -*原因*:这通常是因为应用程序被调度气拒绝,因此没有一个pod被调度。 - -导致拒绝的常见原因有: - -1)任务群组(taskGroups)定义无效。调度程序在应用程序被提交时会进行健全性检查,以确保正确定义所有任务群组,如果这些信息的格式不正确,调度程序将拒绝该应用程序 - -2)任务群组中定义的总最小资源量大于队列的最大资源量,因此调度程序拒绝该应用程序,因为队列的资源量无法满足它。可以通过检查pod事件中的相关消息,或调度器日志来找到更多详细的错误信息。 - -*解决方案*:更正任务群组的定义并重新提交应用程序。 - -### 2.有些占位符没有被分配 -*原因*:占位符也会消耗资源,如果不能全部分配,通常是队列或者集群没有足够的资源分配给它们。在这种情况下,占位符将在一定时间后被清理,该时间由调度策略参数─`placeholderTimeoutInSeconds`所定义。 - -*解决方案*:如果占位符超时了,目前的app将会转为failed状态,无法再被调度。如果您愿意等待更长的时间,可以增加占位符超时的值。将来可能会添加倒退策略以提供重试,而不是使应用程序失败。 - -### 3.有些占位符没有被交换 -*原因*:这通常代表应用程序的pod少于任务群组中定义的最小成员数(`minMembers`) - -*解决方案*:检查任务群组字段中的`minMember`并确保其设置正确。`minMember`可以小于实际的pod数,设置大于实际pod数是无效的。 - -### 4.应用程序终止时不会清除占位符 -*原因*:所有占位符都会设置[ownerReference](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents)到应用程序的第一个真实的pod,或控制器参考。如果无法清理占位符,则意味着垃圾回收(garbage collector)的机制不正常。 - -*解决方案*:检查占位符的`ownerReference`和Kubernetes中的垃圾收集器。 - -## 仍然遇到问题? -没问题!Apache Yunikorn社区将很乐意提供帮助。您可以通过以下选项联系社区: - -1. 将您的问题发布到dev@yunikorn.apache.org。 -2. 加入[YuniKorn slack](https://join.slack.com/t/yunikornworkspace/shared_invite/enQtNzAzMjY0OTI4MjYzLTBmMDdkYTAwNDMwNTE3NWVjZWE1OTczMWE4NDI2Yzg3MmEyZjUyYTZlMDE5M2U4ZjZhNmYyNGFmYjY4ZGYyMGE)并将您的问题发布到`#yunikorn-user`频道。 -3. 加入[社区会议](http://yunikorn.apache.org/community/get_involved#community-meetings)并直接与社区成员交谈。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/usergroup_resolution.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/usergroup_resolution.md deleted file mode 100644 index 7702498cd21..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/usergroup_resolution.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -id: usergroup_resolution -title: 解析用户和群组 ---- - - - -## 用户解析 (User resolution) - -用户信息是调度周期的重要概念,他是決定「是否将作业提交到队列」的关键指标之一。Yunikorn调度器依赖k8s Shim来提供用户信息,但在Kubernetes的世界中,没有任何对象可以识别实际用户,这是基于设计使然,可以从这个[页面](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#users-in-kubernetes)中得到更多资讯。 - -在Yunikorn中有两种处理用户和群组的方法。第一种是传统的方式,使用标签`yunikorn.apache.org/usernname`。如果此标签设置在pod上,则该值会自动提取到shim中并被使用。群组解析也在shim中完成,但预设是不启用的。这种方法的问题有两个方面:首先,用户限制可以很容易地被绕过,因为提交者可以自由地将标签设置为任何值,因此这只能在受信任的环境中使用。其次,在shim中识别组别太慢了─将用户分配到多个群组​是不可行的,因为根据身份验证机制(如X509,tokens,LDP,etc)可能很难查找用户属于哪一个群组。 - -由于这些限制很大,为了向后兼容才保留了此方法,且将来可能会被删除。 - -一种更可靠和健全的机制是使用`yunikorn.apache.org/user.info`,其中用户信息中的「允许的用户或群组列表」可以由从外部设置,或者准入控制(admission controller)可以自动将其附加到每个工作负载(workflow)。 - -## 传统的用户处理 - -### 使用`yunikorn.apache.org/username`标签 - -由于kubernetes没有预定义的字段和资源能用于用户信息,且个别集群使用的用户识别工具可能有所不同,于是我们定义了标准的方法来识别用户。Yunikorn需要添加一个kubernetes[标签](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)。这里提供了[推荐的使用方法](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/),预设的标签定义如下: - -|标签|值| -|----------------------------------------------- |--------------------- | -| yunikorn.apache.org/username |用户名。可以重复该条目,但只会使用第一个值。默认的用户是`nobody` | - -举例: -```yaml -metadata: - labels: - yunikorn.apache.org/username:"john" -``` -:::tip -为了让该字段(field)成为唯一识别用户的指标,建议集群管理员使用用户识别工具,将这个标签设为不可变的字段。集群管理员或用户可以自由的使用任何方法或工具来增加这个字段和值。其中包含在提交时手动添加。 -::: - -:::note 假设 -假设: -Yunikorn假设一个应用程序的所有pod都属于同一个用户。我们建议将用户标签添加到应用程序的每个pod。这是为了确保没有任何意外。 -::: - -在[K8s的部署](https://github.com/apache/yunikorn-release/blob/master/helm-charts/yunikorn/templates/deployment.yaml)时,可以通过覆盖`USER_LABEL_KEY`来改变标签`yunikorn.apache.org/username`的默认值,这在已经添加用户标签,或出于某些安全因素下必须修改标签的情况下特别有用。 - -```yaml - env: - - name: USER_LABEL_KEY - value:"custom_user_label" -``` - -### 群组解析 (Group resolution) - -这里包含群组成员解析的定义,此外该功能是可以选择加入或移除的。群组不必是用户或群组对象所提供的一部分。当对象被加到缓存中时,群组将自动根据配置来解析。可以为每个分区(partition)设置连接到缓存的解析器(resolver)。 - -预设的群组解析器是"no resolver"。此解析器仅回传用户明和与用户同名的主要群组。 - -其他解析器: -* 操作系统解析器 -* 测试解析器 - -## 推荐的处理用户的新方式 - -从Yunikorn 1.2开始,可以使用更复杂的用户/群组解析方式。 - -在这种模式下,Yunikorn不再依赖标签`yunikorn.apache.org/username`,而是将`yunikorn.apache.org/user.info`附加到工作负载。通过简单的JSON值,定义用户名和群组: - -```yaml -metadata: - annotations: - yunikorn.apache.org/user.info:" - { - username: \"yunikorn\", - groups: [ - \"developers\", - \"devops\" - ] - }" -``` - -然而,为了加强安全性,在准入控制器中强制执行了以下操作: -* 不是集群中的每个用户都可以附加此注解(annotation),只有在配置允许时才可以使用。 -* 如果缺少注解,则准入控制器将自动添加。 -* 若尝试修改此注解将会被拒绝。 - -我们不只在pods上这样做,而是在Deployments,ReplicaSet,DeamonSet,StatefulSet,Jobs和CronJobs上都这样做。 - -此外,群组解析器不再需要放在k8s-shim中。 - -### 配置准入控制器 - -准入控制可以在`yunikorn-configs`的configmap中被配置。所有条目都以前缀`admissionController.accessControl.`开头。 - -|变量|默认值|描述| -|--|--|--| -|`bypassAuth`|false|允许任何外部用户使用用户信息集创建pod| -|`trustControllers`|true|允许Kubernetes控制器的用户创建带有用户信息集的pod| -|`systemUsers`|"^system:serviceaccount:kube-system:"|允许控制器符物帐号列表使用正则表达式| -|`externalUsers`|""|在「允许的外部用户列表」上使用正则表达式| -|`externalGroups`|""|在「允许的外部群组列表」上使用正则表达式| - -如果`bypassAuth`设置为`true`,但注解不存在且设定了已遗弃的用户标签,则准入控制器将不会把注解加到pod中。如果未设置注解也未设置用户标签,则新的注解将会被加入。 -在`bypassAuth`为`false`(默认值)的情况下,准入控制器将始终添加新的注解,而不管是否存在已弃用的标签。 - -在某些情况下,必须将用户和群组在提交时提供给Yunikorn,因为用户和群组管理由外部系统提供,查找机制并不简单。因此,在这些情况下,可以将`externalUsers`和`externalGroups`配置为正则表达式。其中,匹配的用户或群组就可以将`yunikorn.apache.org/user.info`设置为任意值。但这会影响Yunikorn内部的调度,因此必须仔细设置这些属性。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_flink.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_flink.md deleted file mode 100644 index 40eb05b1978..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_flink.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: run_flink -title: 运行Flink作业 -description: 如何与YuniKorn一起运行Flink作业 -image: https://svn.apache.org/repos/asf/flink/site/img/logo/png/100/flink_squirrel_100_color.png -keywords: - - spark ---- - - - -使用 YuniKorn 在 Kubernetes 上运行 [Apache Flink](https://flink.apache.org/) 非常容易。 -根据在 Kubernetes 上运行 Flink 的模式不同,配置会略有不同。 - -## Standalone(独立)模式 - -请关注 [Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/kubernetes.html) 以获取 standalone 部署模式的细节和示例。 -在这种模式下,我们可以直接在 Deployment/Job spec 中添加需要的标签(applicationId 和 queue)来使用 YuniKorn 调度器运行 flink 应用程序,以及 [使用 YuniKorn 调度器运行 workloads](#run-workloads-with-yunikorn-scheduler) . - -## Native(原生)模式 - -请关注 [原生 Kubernetes 设置](https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/native_kubernetes.html) 以获取原生部署模式的细节和示例。 -只有 Flink 1.11 或更高版本才支持在 native 模式下使用 YuniKorn 调度程序运行 Flink 应用程序,我们可以利用两个 Flink 配置 `kubernetes.jobmanager.labels` 和 `kubernetes.taskmanager.labels` 来设置所需的标签。 -例子: - -* 启动一个 Flink session -``` -./bin/kubernetes-session.sh \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dresourcemanager.taskmanager-timeout=3600000 \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox -``` - -* 启动一个 Flink application -``` -./bin/flink run-application -p 8 -t kubernetes-application \ - -Dkubernetes.cluster-id= \ - -Dtaskmanager.memory.process.size=4096m \ - -Dkubernetes.taskmanager.cpu=2 \ - -Dtaskmanager.numberOfTaskSlots=4 \ - -Dkubernetes.container.image= \ - -Dkubernetes.jobmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - -Dkubernetes.taskmanager.labels=applicationId:MyOwnApplicationId,queue:root.sandbox \ - local:///opt/flink/usrlib/my-flink-job.jar -``` \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_mpi.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_mpi.md deleted file mode 100644 index 374c5ca1e68..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_mpi.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: run_mpi -title: 运行MPI作业 -description: 在Yunikorn中运行MPI作业 -keywords: - - mpi ---- - - - -本指南介绍将介绍如何设置[MPI Operator](https://github.com/kubeflow/mpi-operator),以及如何使用YuniKorn调度程序运行MPIJob。 - -## 安装MPI操作器 -您可以使用以下命令安装MPI操作器。如果您在安装时遇到问题,请参阅[此文档](https://github.com/kubeflow/mpi-operator)了解详细信息。 -``` -kubectl create -f https://raw.githubusercontent.com/kubeflow/mpi-operator/master/deploy/v2beta1/mpi-operator.yaml -``` - -## 运行MPI作业 -此示例显示如何运行MPI应用程序。 - -此程序将印出一些关于workers的基础信息,然后计算圆周率的近似值。 - -这是一个计算圆周率的[YAML示例](https://github.com/apache/yunikorn-k8shim/blob/master/deployments/examples/mpioperator/Pi/pi.yaml): - -```yaml -apiVersion: kubeflow.org/v2beta1 -kind: MPIJob -metadata: - name: pi -spec: - slotsPerWorker: 1 - runPolicy: - cleanPodPolicy: Running - ttlSecondsAfterFinished: 60 - sshAuthMountPath: /home/mpiuser/.ssh - mpiReplicaSpecs: - Launcher: - replicas: 1 - template: - labels: - applicationId: "mpi_job_pi" - queue: root.mpi - spec: - schedulerName: yunikorn - containers: - - image: mpioperator/mpi-pi - name: mpi-launcher - securityContext: - runAsUser: 1000 - command: - - mpirun - args: - - -n - - "2" - - /home/mpiuser/pi - resources: - limits: - cpu: 1 - memory: 1Gi - Worker: - replicas: 2 - template: - labels: - applicationId: "mpi_job_pi" - queue: root.mpi - spec: - schedulerName: yunikorn - containers: - - image: mpioperator/mpi-pi - name: mpi-worker - securityContext: - runAsUser: 1000 - command: - - /usr/sbin/sshd - args: - - -De - - -f - - /home/mpiuser/.sshd_config - resources: - limits: - cpu: 1 - memory: 1Gi -``` -创建一个MPIJob。 -``` -kubectl create -f deployments/examples/mpioperator/Pi/pi.yaml -``` - -我们在圆周率示例中添加了Yunikorn标签,以演示如何使用yunikorn调度程序。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_nvidia.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_nvidia.md deleted file mode 100644 index 8758c1eb89e..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_nvidia.md +++ /dev/null @@ -1,347 +0,0 @@ ---- -id: run_nvidia -title: 运行NVIDIA GPU作业 -description: 如何使用Yunikorn运行通用的GPU调度示例 -keywords: - - NVIDIA GPU ---- - - - -## Yunikorn 与 NVIDIA GPUs -本指南概述了如何设置NVIDIA设备插件,该插件使用户可以在Yunikorn上运行GPU。如需更详细信息,请查看 [**使用GPU的Kubernetes**](https://docs.nvidia.com/datacenter/cloud-native/kubernetes/install-k8s.html#option-2-installing-kubernetes-using-kubeadm)。 - -### 先决条件 -在按照以下步骤之前,需要在 [**设置GPU的Kubernetes**](https://docs.nvidia.com/datacenter/cloud-native/kubernetes/install-k8s.html#install-kubernetes)上部署Yunikorn。 - -### 安装NVIDIA设备插件 -添加nvidia-device-plugin Helm存储库。 -``` -helm repo add nvdp https://nvidia.github.io/k8s-device-plugin -helm repo update -helm repo list -``` - -验证插件的最新发布版本是否可用。 -``` -helm search repo nvdp --devel -NAME CHART VERSION APP VERSION DESCRIPTION -nvdp/nvidia-device-plugin 0.12.3 0.12.3 A Helm chart for ... -``` - -部署设备插件。 -``` -kubectl create namespace nvidia -helm install --generate-name nvdp/nvidia-device-plugin --namespace nvidia --version 0.12.3 -``` - -检查Pod的状态以确保NVIDIA设备插件正在运行。 -``` -kubectl get pods -A - -NAMESPACE NAME READY STATUS RESTARTS AGE -kube-flannel kube-flannel-ds-j24fx 1/1 Running 1 (11h ago) 11h -kube-system coredns-78fcd69978-2x9l8 1/1 Running 1 (11h ago) 11h -kube-system coredns-78fcd69978-gszrw 1/1 Running 1 (11h ago) 11h -kube-system etcd-katlantyss-nzxt 1/1 Running 3 (11h ago) 11h -kube-system kube-apiserver-katlantyss-nzxt 1/1 Running 4 (11h ago) 11h -kube-system kube-controller-manager-katlantyss-nzxt 1/1 Running 3 (11h ago) 11h -kube-system kube-proxy-4wz7r 1/1 Running 1 (11h ago) 11h -kube-system kube-scheduler-katlantyss-nzxt 1/1 Running 4 (11h ago) 11h -kube-system nvidia-device-plugin-1659451060-c92sb 1/1 Running 1 (11h ago) 11h -``` - -### 测试NVIDIA设备插件 -创建一个GPU测试的YAML文件。 -``` -# gpu-pod.yaml - apiVersion: v1 - kind: Pod - metadata: - name: gpu-operator-test - spec: - restartPolicy: OnFailure - containers: - - name: cuda-vector-add - image: "nvidia/samples:vectoradd-cuda10.2" - resources: - limits: - nvidia.com/gpu: 1 -``` -部署应用程序。 -``` -kubectl apply -f gpu-pod.yaml -``` -检查日志以确保应用程序成功完成。 -``` -kubectl get pods gpu-operator-test - -NAME READY STATUS RESTARTS AGE -gpu-operator-test 0/1 Completed 0 9d -``` -检查结果。 -``` -kubectl logs gpu-operator-test - -[Vector addition of 50000 elements] -Copy input data from the host memory to the CUDA device -CUDA kernel launch with 196 blocks of 256 threads -Copy output data from the CUDA device to the host memory -Test PASSED -Done -``` - ---- -## 启用GPU时间切片( 可选 ) -GPU时间分片允许多租户共享单个GPU。 -要了解GPU时间分片的工作原理,请参阅[**在Kubernetes中使用GPU的时间切片**](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/gpu-sharing.html#introduction)。此页面介绍了使用 [**NVIDIA GPU Operator**](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/gpu-operator)启用Yunikorn中GPU调度的方法。 - - -### 配置 -以下示例说明在ConfigMap中指定多个配置。 -```yaml -# time-slicing-config.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: time-slicing-config - namespace: nvidia -data: - a100-40gb: |- - version: v1 - sharing: - timeSlicing: - resources: - - name: nvidia.com/gpu - replicas: 8 - - name: nvidia.com/mig-1g.5gb - replicas: 2 - - name: nvidia.com/mig-2g.10gb - replicas: 2 - - name: nvidia.com/mig-3g.20gb - replicas: 3 - - name: nvidia.com/mig-7g.40gb - replicas: 7 - rtx-3070: |- - version: v1 - sharing: - timeSlicing: - resources: - - name: nvidia.com/gpu - replicas: 8 -``` - -:::note -如果节点上的GPU类型不包括a100-40gb或rtx-3070,您可以根据现有的GPU类型修改YAML文件。例如,在本地Kubernetes集群中只有多个rtx-2080ti,而rtx-2080ti不支持MIG,因此无法替代a100-40gb。但rtx-2080ti支持时间切片,因此可以替代rtx-3070。 -::: - -:::info -MIG支持于2020年添加到Kubernetes中。有关其工作原理的详细信息,请参阅 [**在Kubernetes中支援MIG**](https://www.google.com/url?q=https://docs.google.com/document/d/1mdgMQ8g7WmaI_XVVRrCvHPFPOMCm5LQD5JefgAh6N8g/edit&sa=D&source=editors&ust=1655578433019961&usg=AOvVaw1F-OezvM-Svwr1lLsdQmu3) 。 -::: - -在operator命名空间nvidia,创建一个ConfigMap。 -```bash -kubectl create namespace nvidia -kubectl create -f time-slicing-config.yaml -``` - -### 安装NVIDIA GPU Operator -添加nvidia-gpu-operator Helm存储库。 -```bash -helm repo add nvidia https://helm.ngc.nvidia.com/nvidia -helm repo update -helm repo list -``` - - -使用NVIDIA GPU Operator启用共享GPU。 -- 在启用时间切片的情况下首次安装NVIDIA GPU Operator。 - ```bash - helm install gpu-operator nvidia/gpu-operator \ - -n nvidia \ - --set devicePlugin.config.name=time-slicing-config - ``` - -- 对于已安装GPU Operator的情况下,动态启用时间切片。 - ```bash - kubectl patch clusterpolicy/cluster-policy \ - -n nvidia --type merge \ - -p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config"}}}}' - ``` - -### 应用时间分片配置 -有两种方法: -- 集群范围 - -通过传递时间分片ConfigMap名称和默认配置来安装GPU Operator。 - ```bash - kubectl patch clusterpolicy/cluster-policy \ - -n nvidia --type merge \ - -p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config", "default": "rtx-3070"}}}}' - ``` - -- 在特定节点上 - -使用ConfigMap中所需的时间切片配置对节点进行标记。 - ```bash - kubectl label node nvidia.com/device-plugin.config=rtx-3070 - ``` - - -一旦安装了GPU Operator和时间切片GPU,检查Pod的状态以确保所有容器都在运行,并且验证已完成。 -```bash -kubectl get pods -n nvidia -``` - -```bash -NAME READY STATUS RESTARTS AGE -gpu-feature-discovery-qbslx 2/2 Running 0 20h -gpu-operator-7bdd8bf555-7clgv 1/1 Running 0 20h -gpu-operator-node-feature-discovery-master-59b4b67f4f-q84zn 1/1 Running 0 20h -gpu-operator-node-feature-discovery-worker-n58dv 1/1 Running 0 20h -nvidia-container-toolkit-daemonset-8gv44 1/1 Running 0 20h -nvidia-cuda-validator-tstpk 0/1 Completed 0 20h -nvidia-dcgm-exporter-pgk7v 1/1 Running 1 20h -nvidia-device-plugin-daemonset-w8hh4 2/2 Running 0 20h -nvidia-device-plugin-validator-qrpxx 0/1 Completed 0 20h -nvidia-operator-validator-htp6b 1/1 Running 0 20h -``` -验证时间分片配置是否成功应用。 -```bash -kubectl describe node -``` - -```bash -... -Capacity: - nvidia.com/gpu: 8 -... -Allocatable: - nvidia.com/gpu: 8 -... -``` - -### 测试GPU时间切片 -创建一个工作负载测试文件 plugin-test.yaml。 -```yaml -# plugin-test.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nvidia-plugin-test - labels: - app: nvidia-plugin-test -spec: - replicas: 5 - selector: - matchLabels: - app: nvidia-plugin-test - template: - metadata: - labels: - app: nvidia-plugin-test - spec: - tolerations: - - key: nvidia.com/gpu - operator: Exists - effect: NoSchedule - containers: - - name: dcgmproftester11 - image: nvidia/samples:dcgmproftester-2.1.7-cuda11.2.2-ubuntu20.04 - command: ["/bin/sh", "-c"] - args: - - while true; do /usr/bin/dcgmproftester11 --no-dcgm-validation -t 1004 -d 300; sleep 30; done - resources: - limits: - nvidia.com/gpu: 1 - securityContext: - capabilities: - add: ["SYS_ADMIN"] -``` - - -创建一个具有多个副本的部署。 -```bash -kubectl apply -f plugin-test.yaml -``` - -验证所有五个副本是否正在运行。 - -- 在Pod群中 - ```bash - kubectl get pods - ``` - - ```bash - NAME READY STATUS RESTARTS AGE - nvidia-plugin-test-677775d6c5-bpsvn 1/1 Running 0 8m8s - nvidia-plugin-test-677775d6c5-m95zm 1/1 Running 0 8m8s - nvidia-plugin-test-677775d6c5-9kgzg 1/1 Running 0 8m8s - nvidia-plugin-test-677775d6c5-lrl2c 1/1 Running 0 8m8s - nvidia-plugin-test-677775d6c5-9r2pz 1/1 Running 0 8m8s - ``` -- 在节点中 - ```bash - kubectl describe node - ``` - - ```bash - ... - Allocated resources: - (Total limits may be over 100 percent, i.e., overcommitted.) - Resource Requests Limits - -------- -------- ------ - ... - nvidia.com/gpu 5 5 - ... - ``` -- 在NVIDIA系统管理界面中 - ```bash - nvidia-smi - ``` - - ```bash - +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 520.61.05 Driver Version: 520.61.05 CUDA Version: 11.8 | - |-------------------------------+----------------------+----------------------+ - | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | - | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | - | | | MIG M. | - |===============================+======================+======================| - | 0 NVIDIA GeForce ... On | 00000000:01:00.0 On | N/A | - | 46% 86C P2 214W / 220W | 4297MiB / 8192MiB | 100% Default | - | | | N/A | - +-------------------------------+----------------------+----------------------+ - - +-----------------------------------------------------------------------------+ - | Processes: | - | GPU GI CI PID Type Process name GPU Memory | - | ID ID Usage | - |=============================================================================| - | 0 N/A N/A 1776886 C /usr/bin/dcgmproftester11 764MiB | - | 0 N/A N/A 1776921 C /usr/bin/dcgmproftester11 764MiB | - | 0 N/A N/A 1776937 C /usr/bin/dcgmproftester11 764MiB | - | 0 N/A N/A 1777068 C /usr/bin/dcgmproftester11 764MiB | - | 0 N/A N/A 1777079 C /usr/bin/dcgmproftester11 764MiB | - +-----------------------------------------------------------------------------+ - ``` - -- 在Yunikorn用户界面中的应用程序中。 -![](../../assets/yunikorn-gpu-time-slicing.png) \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_spark.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_spark.md deleted file mode 100644 index 45791a18427..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/run_spark.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: run_spark -title: 运行Spark作业 -description: 如何使用YuniKorn运行Spark作业 -keywords: - - spark ---- - - - -:::note 注意 -本文档假设您已安装YuniKorn及其准入控制器。请参阅 [开始](../../get_started/get_started.md) 查看如何操作。 -::: - -## 为Spark准备docker镜像 - -要在Kubernetes上运行Spark,您需要Spark的docker镜像。您可以 -1)使用Spark团队提供的docker镜像 -2)从头开始构建一个镜像。如果你想建立自己的Spark的docker镜像,您可以找到 [完整说明](https://spark.apache.org/docs/latest/building-spark.html) -在 Spark 文档中。简化步骤: -* 下载一个支持Kubernetes的Spark版本,URL: https://github.com/apache/spark -* 构建支持Kubernetes的Spark版本: -```shell script -./buid/mvn -Pkubernetes -DskipTests clean package -``` -建议使用[dockerhub](https://hub.docker.com/r/apache/spark/tags)中不同spark版本的官方镜像 - -## 为Spark作业创建一个命名空间 - -创建一个命名空间: - -```shell script -cat < - -本章节概述了如何设置 [training-operator](https://github.com/kubeflow/training-operator) 以及如何使用 YuniKorn 调度器运行 Tensorflow 作业。 -training-operator 是由 Kubeflow 维护的一体化集成的训练 operator。它不仅支持 TensorFlow,还支持 PyTorch、XGboots 等。 - -## 安装 training-operator -您可以使用以下命令在 kubeflow 命名空间中默认安装 training operator。如果安装有问题, -请参阅 [此文档](https://github.com/kubeflow/training-operator#installation) 来查找相关的详细信息。 -``` -kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone?ref=v1.3.0" -``` - -## 准备 docker 镜像 -在开始于 Kubernetes 上运行 TensorFlow 作业之前,您需要构建 docker 镜像。 -1. 从 [deployment/examples/tfjob](https://github.com/apache/yunikorn-k8shim/tree/master/deployments/examples/tfjob) 上下载文件 -2. 使用以下命令构建这个 docker 镜像 - -``` -docker build -f Dockerfile -t kubeflow/tf-dist-mnist-test:1.0 . -``` - -## 运行一个 TensorFlow 作业 -以下是一个使用 MNIST [样例](https://github.com/apache/yunikorn-k8shim/blob/master/deployments/examples/tfjob/tf-job-mnist.yaml) 的 TFJob yaml. - -```yaml -apiVersion: kubeflow.org/v1 -kind: TFJob -metadata: - name: dist-mnist-for-e2e-test - namespace: kubeflow -spec: - tfReplicaSpecs: - PS: - replicas: 2 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 - Worker: - replicas: 4 - restartPolicy: Never - template: - metadata: - labels: - applicationId: "tf_job_20200521_001" - queue: root.sandbox - spec: - schedulerName: yunikorn - containers: - - name: tensorflow - image: kubeflow/tf-dist-mnist-test:1.0 -``` -创建 TFJob -``` -kubectl create -f deployments/examples/tfjob/tf-job-mnist.yaml -``` - -您可以从 YuniKorn UI 中查看作业信息。 如果您不知道如何访问 YuniKorn UI, -请阅读此 [文档](../../get_started/get_started.md#访问-web-ui)。 - -![tf-job-on-ui](../../assets/tf-job-on-ui.png) - -## 使用GPU Time-slicing -### 前提 -要使用 Time-slicing GPU,您需要先设定丛集以让GPU和Time-slicing GPU能被使用。 -- 节点上必须连接GPU -- Kubernetes版本为1.24 -- 丛集中需要安装 GPU drivers -- 透过 [GPU Operator](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/getting-started.html) 自动化的建置与管理节点中的 NVIDIA 软体组件 -- 在Kubernetes中设定 [Time-Slicing GPUs in Kubernetes](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/gpu-sharing.html) - - -在安装完 GPU Operator 及 Time-slicing GPU 以后,确认pods的状态以确保所有的containers正在运行或完成: -```shell script -kubectl get pod -n gpu-operator -``` -```shell script -NAME READY STATUS RESTARTS AGE -gpu-feature-discovery-fd5x4 2/2 Running 0 5d2h -gpu-operator-569d9c8cb-kbn7s 1/1 Running 14 (39h ago) 5d2h -gpu-operator-node-feature-discovery-master-84c7c7c6cf-f4sxz 1/1 Running 0 5d2h -gpu-operator-node-feature-discovery-worker-p5plv 1/1 Running 8 (39h ago) 5d2h -nvidia-container-toolkit-daemonset-zq766 1/1 Running 0 5d2h -nvidia-cuda-validator-5tldf 0/1 Completed 0 5d2h -nvidia-dcgm-exporter-95vm8 1/1 Running 0 5d2h -nvidia-device-plugin-daemonset-7nzvf 2/2 Running 0 5d2h -nvidia-device-plugin-validator-gj7nn 0/1 Completed 0 5d2h -nvidia-operator-validator-nz84d 1/1 Running 0 5d2h -``` -确认时间片设定是否被成功的使用: -```shell script -kubectl describe node -``` - -```shell script -Capacity: - nvidia.com/gpu: 16 -... -Allocatable: - nvidia.com/gpu: 16 -... -``` -### 使用GPU测试TensorFlow job -在这个段落中会在 Time-slicing GPU 的支援下,测试及验证TFJob的运行 - -1. 新建一个workload的测试档案tf-gpu.yaml: - ```shell script - vim tf-gpu.yaml - ``` - ```yaml - apiVersion: "kubeflow.org/v1" - kind: "TFJob" - metadata: - name: "tf-smoke-gpu" - namespace: kubeflow - spec: - tfReplicaSpecs: - PS: - replicas: 1 - template: - metadata: - creationTimestamp: - labels: - applicationId: "tf_job_20200521_001" - spec: - schedulerName: yunikorn - containers: - - args: - - python - - tf_cnn_benchmarks.py - - --batch_size=32 - - --model=resnet50 - - --variable_update=parameter_server - - --flush_stdout=true - - --num_gpus=1 - - --local_parameter_device=cpu - - --device=cpu - - --data_format=NHWC - image: docker.io/kubeflow/tf-benchmarks-cpu:v20171202-bdab599-dirty-284af3 - name: tensorflow - ports: - - containerPort: 2222 - name: tfjob-port - workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks - restartPolicy: OnFailure - Worker: - replicas: 1 - template: - metadata: - creationTimestamp: null - labels: - applicationId: "tf_job_20200521_001" - spec: - schedulerName: yunikorn - containers: - - args: - - python - - tf_cnn_benchmarks.py - - --batch_size=32 - - --model=resnet50 - - --variable_update=parameter_server - - --flush_stdout=true - - --num_gpus=1 - - --local_parameter_device=cpu - - --device=gpu - - --data_format=NHWC - image: docker.io/kubeflow/tf-benchmarks-gpu:v20171202-bdab599-dirty-284af3 - name: tensorflow - ports: - - containerPort: 2222 - name: tfjob-port - resources: - limits: - nvidia.com/gpu: 2 - workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks - restartPolicy: OnFailure - ``` -2. 创建TFJob - ```shell script - kubectl apply -f tf-gpu.yaml - ``` -3. 在Yunikorn中验证TFJob是否运行 - ![tf-job-gpu-on-ui](../../assets/tf-job-gpu-on-ui.png) - 察看pod的日志: - ```shell script - kubectl logs logs po/tf-smoke-gpu-worker-0 -n kubeflow - ``` - ``` - ....... - ..Found device 0 with properties: - ..name: NVIDIA GeForce RTX 3080 major: 8 minor: 6 memoryClockRate(GHz): 1.71 - - ....... - ..Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: NVIDIA GeForce RTX 3080, pci bus id: 0000:01:00.0, compute capability: 8.6) - ....... - ``` - ![tf-job-gpu-on-logs](../../assets/tf-job-gpu-on-logs.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/workload_overview.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/workload_overview.md deleted file mode 100644 index c7b46a4c378..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.4.0/user_guide/workloads/workload_overview.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: workload_overview -title: 概述 ---- - - - -YuniKorn调度器支持任何的Kubernetes工作负载。所需要的只是确保将Pod规范的 -`schedulerName`字段设置为`yunikorn`并将`applicationId`标签设置为每个应用程序的唯一值: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - labels: - app: sleep - applicationId: "application-sleep-0001" - name: sleep-app-1 -spec: - schedulerName: yunikorn - containers: - - name: sleep-30s - image: "alpine:latest" - command: ["sleep", "30"] - resources: - requests: - cpu: "100m" - memory: "100M" -``` - -此外,如果存在YuniKorn准入控制器,则可以省略“schedulerName”字段,因为它将在新创建的pod上自动设置。 - -## 进阶例子 - -可以在此处找到更进阶的例子: - -* [运行Spark作业](run_spark) -* [运行Flink作业](run_flink) -* [运行TensorFlow作业](run_tf) diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/community/coding_guidelines.md b/i18n/zh-cn/docusaurus-plugin-content-pages/community/coding_guidelines.md deleted file mode 100644 index ee3b0cb2938..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/community/coding_guidelines.md +++ /dev/null @@ -1,153 +0,0 @@ ---- -id: coding_guidelines -title: 编码指南 ---- - - - -# 编码指南 - -## 基础指南 -GO 作为一种语言为代码提供了内置的格式化程序:`gofmt`。 -该项目使用在 `gofmt` 中实现的预定义格式。 -这意味着例如:tabs而不是空格等。 -阅读 [Effective GO](https://golang.org/doc/effective_go.html) 页面了解更多详情。 -在创建拉取请求之前,请确保至少使用 `gofmt` 格式化代码。 - -除了 Effective GO 指南之外,请遵循 [CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments) wiki 页面中的建议。 -wiki 提供了一个很好的代码审查注释库。 -大多数注释将在下面描述的自动检查中进行检查。 - -使用 IDE(如 GoLand 或 Visual Studio Code)时,请使用内置的选项。 -大多数 IDE 将提供大量检查或格式化选项列表,以帮助格式化和指出代码的问题。 -有关 GoLand IDE 的基本设置,请参阅 [IDE 设置](#goland-ide-setup)。 - -## 自动检查 -并非所有代码都会使用 IDE 进行编写。 -即使在贡献者之间,所有安装的设置也可能不同。 -为了帮助保持代码格式一致,[lint](https://en.wikipedia.org/wiki/Lint_(software)) 工具是代码批准的一部分。 - -Go 有大量可用的 lint 工具。 -大多数 lint 工具只检查一件特定的事情。 -一些工具将聚合一些 linter,并提供所有发现的问题的概述。 -对于该项目,我们选择了 [golangci-lint](https://github.com/golangci/golangci-lint) 工具。 -该工具可以在本地运行,并将集成到 GitHub PR 流程中。 - -### 本地安装和运行 -我们可以按照项目提供的 [安装说明](https://golangci-lint.run/usage/install/#local-installation) 进行运行。 -不过根据您的开发系统,说明可能会略有不同。 - -安装工具后,您可以使用标准命令行运行它: -```shell script -golangci-lint run -``` - -这些项目仍然会产生许多警告。 -高影响警告已通过评论修复或忽略,请参阅 [误报](#false-positives)。 - -如果您一直在研究新功能或修复错误,您只想检查已更改的文件。 -您可以使用选项 `--new` 或 `--new-from-rev` 选项运行该工具。 -`--new` 选项只会检查未提交的文件。 -`--new-from-rev` 选项将根据特定提交的修订检查更改。 - -```shell script -# 对于未提交的更改 -golangci-lint run --new -# 针对修订提交的更改 -golangci-lint run --new-from-rev=origin/master -``` - -make命令追加 `lint`: -```shell script -make lint -``` - -`make` 使用 linter 集成检查可执行文件的两个位置: -* `$(go env GOPATH)/bin/` -* `./bin/` - -对于开发人员和 CI 安装,标准的安装位置略有不同。 -通过检查这两个位置,我们可以在本地和自动构建期间运行。 - -make 集成使用 `--new-from-rev` 命令行选项。 -要检查的修改被确定为运行的一部分,以允许它在我们的 CI 构建期间在不同的分支和拉取请求上运行。 -lint 检查是项目的标准 CI 构建运行的一部分。 - -有关如何运行该工具的更多选项和信息,请参阅 golangci-lint 产品文档。 - -### 配置 -为使用它们的两个项目提供了预定义的配置: -* [YuniKorn k8shim](https://github.com/apache/yunikorn-k8shim), 配置文件 [golangci.yml](https://github.com/apache/yunikorn-k8shim/blob/master/.golangci.yml). -* [YuniKorn core](https://github.com/apache/yunikorn-core), 配置文件 [golangci.yml](https://github.com/apache/yunikorn-core/blob/master/.golangci.yml). - -Web 界面是一个 javascript 项目,调度接口只生成了 Go 代码,因此不使用它。 - -### 拉取请求中的集成 -计划是将 `golangci-lint` 检查集成到 GitHub PR 流程中。 - -## 误报 -工具从来都不是 100% 正确的,这个也不是。 -某些问题因太难纠正或不够重要而无法修复。 - -该工具允许向代码添加注释以忽略该问题。 -这些注释应该谨慎使用,因为它们可能会隐藏问题。 -如果使用它们,则应附有注明以解释使用它们的原因。 -```go - var s1 = "ignored by all linters" //nolint - var s2 = "ignored by the linter unused" //nolint:unused -``` -我们不鼓励使用没有特定 linter 的 `nolint` 注释。 - -## GoLand IDE 设置 -GoLand 默认开启了许多检查。 -这些默认值已经提供了很好的覆盖率,并将 linter 发现的许多问题标记为问题。 -要进一步扩大覆盖范围并帮助标记问题,请主动检查以下设置并将其更改为根据屏幕截图的设置。 - -### preferences 偏好 -打开 preferences 窗格并转到:Editor -> Code Style -> Go -需要配置三个选项卡,前两个对于遵守 `gofmt` 和 `goimports` 的基本规则至关重要: - -| | | -|---------|----------------------------------------------| -| Tabs | ![tabs](/img/goland_ide_pref_tabs.png) | -| Imports | ![imports](/img/goland_ide_pref_imports.png) | -| Other | ![other](/img/goland_ide_pref_other.png) | - -上面配置的导入在使用时应该在一个文件中创建 3 组导入: -1. 标准库导入 -2. 第三方导入 -3. YuniKorn 内部导入 - -在文件中,它将为您提供如下所示的导入: -```go -import ( - // 标准库导入 - - // 第三方 - - // YuniKorn 项目导入 -) -``` - -### 检查 -除开有助于突出显示阴影变量的检查,我们才可以使用默认检查。 -阴影变量可能导致难以跟踪和掩盖代码中的错误,应尽可能防止。 - -![检查](/img/goland_ide_pref_inspections.png) diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/community/download.md b/i18n/zh-cn/docusaurus-plugin-content-pages/community/download.md deleted file mode 100644 index 3b0d79432c4..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/community/download.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -id: download -title: Apache YuniKorn (Incubating) ---- - - - -# Apache YuniKorn - -Apache YuniKorn 作为源代码压缩包已经发布。 -最新版本的下载通过镜像站点进行分发。 -旧版本可以从 Apache 存档站点进行下载。 -我们可以使用 GPG 或 SHA-512 检查所有发布文件是否被篡改。 - -为了方便大家,我们发布了预构建的docker镜像。 - -Apache YuniKorn 的最新版本是 v1.4.0。 - -| 版本 | 发布日期 | 源代码下载 | Docker 镜像 | 发布说明 | -|---------|--------------|----------------------------------------------|---------------------------------------------------------------------------------------------|--------------------| -| v1.4.0 | 2023-11-20 | [下载](https://downloads.apache.org/yunikorn/1.4.0/apache-yunikorn-1.4.0-src.tar.gz)
[Checksum](https://downloads.apache.org/yunikorn/1.4.0/apache-yunikorn-1.4.0-src.tar.gz.sha512) & [签名](https://downloads.apache.org/yunikorn/1.4.0/apache-yunikorn-1.4.0-src.tar.gz.asc) | [scheduler](https://hub.docker.com/layers/apache/yunikorn/scheduler-1.4.0/images/sha256-d013be8e3ad7eb8e51ce23951e6899a4b74088e52c3767f3fcc7efcdcc0904f5?context=explore)
[admission-controller](https://hub.docker.com/layers/apache/yunikorn/admission-1.4.0/images/sha256-d93cd7cb480d8bd0ae829d88484b5c8b8f89c843dd0ea48694a636cc0bb00e07?context=explore)
[web](https://hub.docker.com/layers/apache/yunikorn/web-1.4.0/images/sha256-60a732eb04a9690214d2d2f852058a501585091901fb9c0faf66a378e710d452?context=explore)
[scheduler plugin](https://hub.docker.com/layers/apache/yunikorn/scheduler-plugin-1.4.0/images/sha256-7a82c87f4f6caf950529478851f0aaa5da2b225668325ee50b7422c477804e02?context=explore) | [Announcement](/release-announce/1.4.0) | -| v1.3.0 | 2023-06-12 | [下载](https://archive.apache.org/dist/yunikorn/1.3.0/apache-yunikorn-1.3.0-src.tar.gz)
[Checksum](https://archive.apache.org/dist/yunikorn/1.3.0/apache-yunikorn-1.3.0-src.tar.gz.sha512) & [签名](https://archive.apache.org/dist/yunikorn/1.3.0/apache-yunikorn-1.3.0-src.tar.gz.asc) | [scheduler](https://hub.docker.com/layers/apache/yunikorn/scheduler-1.3.0/images/sha256-99a1973728c6684b1da7631dbf015daa1dbf519dbab1ffc8b23fccdfa7ffd0c5?context=explore)
[admission-controller](https://hub.docker.com/layers/apache/yunikorn/admission-1.3.0/images/sha256-3fb41eafcb16ec709879301f0f1cf5ffd18d95e6bb266b20e2971c39c6f6fc94?context=explore)
[web](https://hub.docker.com/layers/apache/yunikorn/web-1.3.0/images/sha256-47c1ff0b58c2c0833bf8662065f7517b8e235dbc2197a9511549ec2ee4b31969?context=explore)
[scheduler plugin](https://hub.docker.com/layers/apache/yunikorn/scheduler-plugin-1.3.0/images/sha256-c3c564033dd8ea07d2f7c5fe272be43b8eba7e7b115ac9b5bee4cf8cae681cd9?context=explore) | [Announcement](/release-announce/1.3.0) | -| v1.2.0 | 2023-02-02 | [下载](https://archive.apache.org/dist/yunikorn/1.2.0/apache-yunikorn-1.2.0-src.tar.gz)
[Checksum](https://archive.apache.org/dist/yunikorn/1.2.0/apache-yunikorn-1.2.0-src.tar.gz.sha512) & [签名](https://archive.apache.org/dist/yunikorn/1.2.0/apache-yunikorn-1.2.0-src.tar.gz.asc) | [scheduler](https://hub.docker.com/layers/apache/yunikorn/scheduler-1.2.0/images/sha256-c3b1a7b2cfec3f3560415519278cc4d94748f0f60ee80dfaf23fcc22dbb8b8e5)
[admission-controller](https://hub.docker.com/layers/apache/yunikorn/admission-1.2.0/images/sha256-7f18fcd080640974ae586d30eda009daf0ad93fa22ada66b0a337ac3fb46b7ac)
[web](https://hub.docker.com/layers/apache/yunikorn/web-1.2.0/images/sha256-706a2895461623f20d4102f0132d66dade9c15edf5cad40065506a4d70c32576)
[scheduler plugin](https://hub.docker.com/layers/apache/yunikorn/scheduler-plugin-1.2.0/images/sha256-d946495946b89d03f7a8f786702d4b350a93f74d52e50bebb6b2bbdcb8e911a4?context=explore) | [Announcement](/release-announce/1.2.0) | - -## 验证签名 - -使用 GPG 验证 Apache YuniKorn 版本: - -- 从镜像站点下载发行版 apache-yunikorn-X.Y.Z-src.tar.gz.tar.gz。 -- 从 Apache 下载签名文件 apache-yunikorn-X.Y.Z-src.tar.gz.tar.gz.asc。 -- 下载 Apache YuniKorn [KEYS](https://downloads.apache.org/incubator/yunikorn/KEYS) 文件。 -- `gpg --import KEYS` -- `gpg --verify apache-yunikorn-X.Y.Z-src.tar.gz.tar.gz.asc` - -注意:在 MacOS-X 上,GNU gpg 实用程序在导入时不会从文件中读取。 -导入命令应该是 `gpg --import < KEYS` - -## 验证 checksum - -要使用 SHA-512 checksum 校验和验证 Apache YuniKorn 版本的完整性: - -- 从镜像站点下载发行版 apache-yunikorn-X.Y.Z-src.tar.gz.tar.gz。 -- 从 Apache 下载校验和 apache-yunikorn-X.Y.Z-src.tar.gz.tar.gz.sha512。 -- 验证 checksum - - 在 MacOS-X: `shasum -c apache-yunikorn-X.Y.Z-src.tar.gz.tar.gz.sha512` - - 在 Linux: `sha512sum -c apache-yunikorn-X.Y.Z-src.tar.gz.tar.gz.sha512` - -## 验证发布 - -本发布是一个源代码版本,您必须先构建后才能使用。 -您需要解压档案文件并按照 `README.md` 文件中的说明构建镜像。 -发布的档案文件中提供了使用本地构建的镜像创建小型集群的脚本和配置。 - -您可以运行如下脚本以获取更多说明并列出验证发布内容所需的工具: -```shell -./validate_cluster.sh -``` -创建的 `kind` 集群是一个小型但功能齐全的 Kubernetes 集群,这里面部署了 Apache YuniKorn。 - -## 旧的发布 - -所有的发布公告都可以在网站上的 [发布公告](/release-announce/) 中找到。 - -您可以在 [档案存储库](https://archive.apache.org/dist/yunikorn/) 中找到以前所有的版本。 -如果您正在寻找在孵化期间制作的旧版本,请检查 [孵化器档案存储库](https://archive.apache.org/dist/incubator/yunikorn/)。 - -档案里包括上表中未提及的所有版本。 - -## License - -该软件在 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) 下获得许可。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/community/events.md b/i18n/zh-cn/docusaurus-plugin-content-pages/community/events.md deleted file mode 100644 index 45efae76e39..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/community/events.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -id: events -title: 事件 ---- - - - -即将举行的会议 ---- - -加入我们 **4:30pm - 5:30pm,太平洋标准时间,2022 年 2 月 16 日** - -我们将于2月16日星期三举办 Apache YuniKorn (Incubating) meetup。快来加入我们吧!自从我们去年11月举行第一次 meetup 以来,社区有了许多新的进展。我们很高兴能安排三场演讲!将此活动添加到您的日历:[:calendar:](https://calendar.google.com/calendar/u/0/r/eventedit/copy/N21jYmxiYWx0c211M2pvMTIydDZxZ2s5ajAgYXBhY2hlLnl1bmlrb3JuQG0/Y2hlbnlhemhhbmdjaGVueWFAZ21haWwuY29t?cid=YXBhY2hlLnl1bmlrb3JuQGdtYWlsLmNvbQ) - -来自 Sync Computing 的 Erica Lin、Luna Xu 和 Sean Gorsky 将展示他们在 Spark autotuner 和 orchestrator 方面的工作。 -说明: -在多租户和异构环境中有效管理数千条数据管道的基础架构和计划是一项艰巨的任务。由于棘手的基础架构搜索空间,糟糕的应用程序调优、资源分配和调度可能导致云计算成本过高、性能下降和作业失败。单独解决这些相互依赖的问题中的每一个通常也不会导致整体上的最佳结果。Sync Computing 将分享他们的 autotuner 和 orchestrator 如何将这些问题作为一个单一的优化问题来共同解决。因此,该解决方案提供了全局优化的 Spark 配置、资源供应和作业调度,具有可配置的优化目标,实现了在云中运行 DAG 工作流的无缝用户体验。我们在 AWS 上通过实验证明 Spark 和 Airflow DAG 最多可节省 77% 的成本或 45% 的性能加速。我们的解决方案在多天的阿里云上的追踪模拟结果上显示,批处理工作负载的总 DAG 完成时间减少了57%。这项工作可能是对 Yunikorn 的补充,我们想与社区讨论潜在的整合策略。 - -来自 Cloudera 的 Craig Condit 将讨论有关最新的 YuniKorn v0.12.2 的情况并简要介绍即将发布的 v1.0 版本的内容。 -说明: -v0.12.2 版本提供了许多新的功能和错误修复。具体来说,准入控制器的实现已被重构,从而使 YuniKorn 调度器能够无缝维护和升级。在即将发布的 v1.0 版本中,我们将见证 YuniKorn 项目的一个重要里程碑。一个令人兴奋的特性是基于 Kubernetes 调度框架的新部署模式,它提供了与默认调度器更好的兼容性,并使新用户更容易试用 YuniKorn。 - -Tingyao Huang 和 Yuteng Chen 都是 YuniKorn 的 committers。他们使用最新的 YuniKorn 代码进行了广泛的性能基准测试。他们的结果表明,与默认的调度器相比,YuniKorn 具有令人信服的吞吐量优势。 - ----- - -过去的Meetup ---- - -**4:30pm - 6:00pm, 太平洋标准时间, 2021 年 11 月 18 日** - -**Wilfred Spiegelenburg** 举办了一场介绍 YuniKorn 社区最新状态的会议。 - -_摘要_: Apache YuniKorn (Incubating) 今年早些时候发布了 v0.11 版本,其中包含了许多新功能和改进,比如 Gang scheduling、REST API 增强和 Kubernetes 1.19 支持。 -在一个月内,我们计划发布主要的 v1.0.0 版本,它将支持 Kubernetes 1.20 和 1.21、改进的节点排序以及大量的小修复和增强功能! -在本次会议中,我们将深入探讨在 Kubernetes 上使用临时占位 pod 背后的 Gang scheduling 实现、通过简化的调度器核心代码和新的节点排序算法显著提高性能。 -请在 [此处](https://docs.google.com/document/d/1-NP0J22-Gp3cZ_hfKyA9htXJw7tlk-BmljF-7CBJg44) 找到本次会议的所有主题。 - ----- - -过去的会议 ---- - -- ApacheCon 2021: [Next Level Spark on Kubernetes with Apache YuniKorn (Incubating)](https://youtu.be/gOST-iT-hj8) :busts_in_silhouette: Weiwei Yang, Chaoran Yu -- ApacheCon Asia 2021: [State Of The Union With Apache YuniKorn (Incubating) - Cloud Native Scheduler For Big Data Usecases](https://www.youtube.com/watch?v=c9UYxzqVMeg) :busts_in_silhouette: Julia Kinga Marton, Sunil Govindan -- Future of Data Meetup: [Apache YuniKorn: Cloud-native Resource Scheduling](https://www.youtube.com/watch?v=j-6ehu6GrwE) :busts_in_silhouette: Wangda Tan, Wilfred Spiegelenburg -- ApacheCon 2020: [Integrate Apache Flink with Cloud Native Ecosystem](https://youtu.be/4hghJCuZk5M) :busts_in_silhouette: Yang Wang, Tao Yang -- Spark+AI Summit 2020: [Cloud-Native Spark Scheduling with YuniKorn Scheduler](https://www.youtube.com/embed/ZA6aPZ9r9wA) :busts_in_silhouette: Gao Li, Weiwei Yang -- Flink Forward 2020: [Energize multi-tenant Flink on K8s with YuniKorn](https://www.youtube.com/embed/NemFKL0kK9U) :busts_in_silhouette: Weiwei Yang, Wilfred Spiegelenburg - - -演示视频 ---- - -请订阅 [YuniKorn Youtube Channel](https://www.youtube.com/channel/UCDSJ2z-lEZcjdK27tTj_hGw) 获取有关新演示的通知! -- [Running YuniKorn on Kubernetes - a 12 minutes Hello-world demo](https://www.youtube.com/watch?v=cCHVFkbHIzo) -- [YuniKorn configuration hot-refresh introduction](https://www.youtube.com/watch?v=3WOaxoPogDY) -- [YuniKorn scheduling and volumes on Kubernetes](https://www.youtube.com/watch?v=XDrjOkMp3k4) -- [YuniKorn placement rules for applications](https://www.youtube.com/watch?v=DfhJLMjaFH0) -- [Federated K8s compute pools with YuniKorn](https://www.youtube.com/watch?v=l7Ydg_ZGZw0&t) - -如果您是 YuniKorn 的布道者,并且您有公开的会议演讲、与 YuniKorn 相关的演示录音,请提交 PR 以扩展此列表! diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/community/get_involved.md b/i18n/zh-cn/docusaurus-plugin-content-pages/community/get_involved.md deleted file mode 100644 index 4aec2b1522d..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/community/get_involved.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: get_involved -title: 进行参与 ---- - - - -# 进行参与 - -Apache YuniKorn 社区非常多样化,我们有来自阿里巴巴、苹果、Cloudera、Linkedin、微软、Nvidia、腾讯、优步等(按英文字母顺序排序)。 -社区深信这种多样性的重要性和 “The Apache Way” 的价值。 -我们欢迎任何形式的贡献、代码、文档或建议!:smiley: 别等了,现在就加入我们吧! - -## 如何加入 YuniKorn 社区 - -请通过以下渠道之一加入我们: - -### 通过 github 贡献 -- 这里解释了贡献项目的基本步骤 - [如何贡献](how_to_contribute) - -### 沟通渠道 - -- 邮件列表: - - 对于希望为项目开发做出贡献或讨论的人: [dev@yunikorn.apache.org](mailto:dev@yunikorn.apache.org) - 订阅: dev@ [订阅](mailto:dev-subscribe@yunikorn.apache.org?subject="subscribe%20to%20YuniKorn%20dev%20list") ([退订](mailto:dev-unsubscribe@yunikorn.apache.org?subject="unsubscribe%20from%20YuniKorn%20dev%20list") [归档](https://lists.apache.org/list.html?dev@yunikorn.apache.org)) - - 对于 JIRA 问题更新订阅: issues@ [订阅](mailto:issues-subscribe@yunikorn.apache.org?subject="subscribe%20to%20YuniKorn%20issues%20list") ([退订](mailto:issues-unsubscribe@yunikorn.apache.org?subject="unsubscribe%20from%20YuniKorn%20issues%20list") [归档](https://lists.apache.org/list.html?issues@yunikorn.apache.org)) - - 对于 GitHub 拉取请求消息订阅: reviews@ [订阅](mailto:reviews-subscribe@yunikorn.apache.org?subject="subscribe%20to%20YuniKorn%20reviews%20list") ([退订](mailto:reviews-unsubscribe@yunikorn.apache.org?subject="unsubscribe%20from%20YuniKorn%20reviews%20list") [归档](https://lists.apache.org/list.html?reviews@yunikorn.apache.org)) - - -- 我们使用 [Slack](https://slack.com/) 作为我们的协作系统, 您可以通过访问 [这个链接](https://join.slack.com/t/yunikornworkspace/shared_invite/enQtNzAzMjY0OTI4MjYzLTBmMDdkYTAwNDMwNTE3NWVjZWE1OTczMWE4NDI2Yzg3MmEyZjUyYTZlMDE5M2U4ZjZhNmYyNGFmYjY4ZGYyMGE) 来加入我们。 -目前,我们在工作区中有以下频道:`#yunikorn-dev` 和 `#yunikorn-user`。 - -- 我们会定期进行多个时区和语言的社区同步,请查找[社区会议](#community-meetings) 来参加在线会议。 - -### 社区会议 - -#### 目标受众: -- 有兴趣为 YuniKorn 项目做出贡献的开发人员。 -- 正在使用或有兴趣了解该项目的用户。 - -#### 日程 - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - - 📆 美国太平洋时间每周三上午 9:30 每两周一次。 单击此处加入 Zoom 会议。 - 📆 中国标准时间 (GMT+8) 每周三下午 1:00。 单击此处加入 Zoom 会议。 - - -#### 资源 - -- 会议记录: [Google 文档](https://docs.google.com/document/d/165gzC7uhcKc5XDWiMYSRKBiPQBy2tDtXADUPuhGlUa0/edit#heading=h.461goivmz24v) - -- 日历: [Google 日历](https://calendar.google.com/calendar/u/0?cid=YXBhY2hlLnl1bmlrb3JuQGdtYWlsLmNvbQ) :point_left: - -## 如何向 YuniKorn 社区分享反馈 - -我们欢迎您试用我们的最新版本并分享您的经验。 - -无论如何,如果您遇到任何问题: -- 根据我们的 [指南](reporting_issues) 在 JIRA 中提出问题或反馈。 -- 在 YuniKorn slack `#yunikorn-user` 频道中阐明/寻求帮助 - -### 其他反馈机制 -- 如果您认为,我们可以在此文档中添加更多内容或为开发人员添加其他文档链接(包括设置等),请在 YuniKorn 文档下提出问题。具体可以参阅我们的 [指南](reporting_issues)。 -- 任何其他支持请在 YuniKorn slack `#general` 频道请求 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/community/how_to_contribute.md b/i18n/zh-cn/docusaurus-plugin-content-pages/community/how_to_contribute.md deleted file mode 100644 index c71e957bb3d..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/community/how_to_contribute.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: how_to_contribute -title: 如何贡献 ---- - - - -# 如何贡献 - -YuniKorn 使用: -* JIRA 用于问题跟踪。 -* GitHub 用于 Pull Requests(以后简称拉取请求)来管理代码审查和更改本身。 -* Markdown 文档,版本化并存储在网站存储库中。 - -## Jira 注册 - -2022 年 11 月,由于虚假 Jira 帐户的涌入造成大量垃圾邮件,Apache Infra 终止了 ASF Jira 帐户的公共注册。 -这篇 [博客文章 - 英语](https://infra.apache.org/blog/jira-public-signup-disabled.html) 讨论了这个决定。 -如果您想为 YuniKorn 开一个 Jira 票证并且没有 ASF Jira 账户,YuniKorn PMC 可以为您创建一个账户。 - -步骤如下: -1. 点击 [申请Jira账户](https://selfserve.apache.org/jira-account.html)。 -2. ASF 项目选择 **yunikorn** 并填写表单。 -3. 等待Yunikorn PMC的批准。 - -## 发现问题 -我们使用 JIRA 问题库来跟踪该项目的错误。 -找到您想要处理的问题,或者如果您发现了新问题,请提交新问题。 -有关报告问题的帮助,请查看 [如何报告问题](reporting_issues)。 - -开始使用代码库的最简单方法是选择一个非常简单的 JIRA 问题并开始工作。 -这将帮助您熟悉代码库、构建系统、审查过程等。 -我们在 [此处](https://issues.apache.org/jira/issues/?jql=project%3DYUNIKORN%20AND%20status%3DOpen%20AND%20labels%3Dnewbie) 标记这些入门错误。 - -如果没有人在处理现有问题,请您在只想打算尽快处理该问题时将其分配给自己。 -如果您选择现有的 JIRA,请查找链接到 JIRA ticket 的拉取请求。 -有人可能已经在处理它并且没有分配 ticket。 -具有拉取请求链接的 JIRA 将具有标签 `pull-request-available`,并且可以在问题链接下找到拉取请求的链接。 - -对于任何不只是微不足道的更改,例如拼写错误或一行代码更改,在公开的渠道如slack或者邮件列表讨论您将如何解决这个问题将很有帮助。 -如果您在开始编写修复程序之前已经从 YuniKorn 社区获得了支持,那么您更有可能审查并提交您的补丁程序。 - -如果您无法将 JIRA 分配给自己,请请求社区帮助分配并将您添加到 JIRA 的贡献者列表中。 - -## 修复问题 -必须在 `master` 分支上创建修复或改进。 -将相关的 YuniKorn 项目 fork 到您自己的项目中并签出 `master` 分支。 -确保在开始之前签出最新的代码修订。 -创建一个分支来处理,一个好名字是你正在处理的 JIRA ID。 - -现在可以开始编码了!在编写补丁时,请牢记以下几点: - -在您的补丁中需要包含测试。 -如果您的补丁添加了功能或修复了错误并且不包括测试,则通常不会被接受。 -如果您不确定如何为特定组件编写测试,请在 JIRA 上寻求指导。 - -您的补丁应该只包含对 JIRA 描述的问题的修复,超过改范围应该由新的 JIRA 来跟踪。这样的原则有利于代码的维护和审核。 -一般来说,如果您在处理特定功能时发现错误,请为该错误提交 JIRA,并检查您是否可以将其分配给自己并独立于该功能进行修复。 -这有助于我们区分错误修复和功能,并让我们构建稳定的维护版本。 - -确保您已遵守 [编码指南](coding_guidelines) 中的建议。 -在您提交之前,您还应该使用 `make test` 运行完整的测试套件。 -这样能确保所有测试都通过。 - -最后,请写一个好的、清晰的提交信息,并带有一个简短的描述性标题。 -描述性标题必须以您正在处理的 JIRA ID 开头。 -一个例子是:`[YUNIKORN-2] Support Gang Scheduling`。 -提交消息将用于预填充拉取请求的信息。 -消息中的 JIRA ID 将自动链接拉取请求和 JIRA。 -下面的消息可用于解释问题是什么,以及如何解决。 - -## 创建拉取请求 -请使用您的补丁在 github 上创建一个拉取请求。 -有关所有的详细信息,请参阅 [开启拉取请求](https://help.github.com/articles/using-pull-requests/)。 - -对于提交者:您可以使用 GitHub UI 创建新分支、推送更改并创建 PR。 -对于贡献者:您已经 fork 了存储库并将您的更改提交到您的 fork。 -使用 GitHub UI 使用 `compare across forks` 选项创建 PR。 - -拉取请求描述必须包含您正在处理的 JIRA 链接。 -如果您如上所述设置提交消息,则拉取请求将自动获取它。 -如果您没有这样做,您可以修改拉取请求的描述以添加 JIRA ID。 -例如,链接到 [YUNIKORN-2](https://issues.apache.org/jira/browse/YUNIKORN-2) 的拉取请求应具有如下描述: -`[YUNIKORN-2] Support Gang Scheduling` - -## 提交更改 -当更改被批准后,它将被提交到存储库的 `master` 分支。 -提交消息必须在第一行包含 JIRA,并且应该包含 `Closes #1`,这样一个提交将自动关闭 PR。 -JIRA 不会自动关闭。 - -## 如果仍有问题? -如果您不确定某些事情,请尝试遵循现有代码库的样式。 -看看代码中是否有其他例子做类似的事情。 -也可以在 [dev@yunikorn.apache.org](mailto:dev@yunikorn.apache.org) 列表中提问。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/community/people.md b/i18n/zh-cn/docusaurus-plugin-content-pages/community/people.md deleted file mode 100644 index 1d0f93b34d0..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/community/people.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: people -title: 我们是谁 ---- - - - -## 项目成员 - -YuniKorn 社区是开放的、多样化的和协作的。 -它不隶属于任何组织,并由项目成员分担管理和维护项目的责任。 -社区中的成员包括孵化项目管理委员会 ([PMC](https://www.apache.org/dev/pmc.html)) 的成员和 [Committers](https://infra.apache.org/new-committers-guide.html#what-is-a-committer)。 - -## PMC - -| 公开名称 | ApacheID | 组织 | 时区
(UTC) | -|-------------------------|-------------|------------|---------------| -| Akhil PB | akhilpb | Cloudera | +5.5 | -| Arun Suresh | asuresh | Oracle | -8 | -| Carlo Curino | curino | Microsoft | -8 | -| Chaoran Yu | yuchaoran | Apple | -8 | -| Chenya Zhang | chenya | Apple | -8 | -| Craig Condit | ccondit | Cloudera | -6 | -| DB Tsai | dbtsai | Apple | -8 | -| Felix Cheung | felixcheung | SafeGraph | -8 | -| Holden Karau | holden | Netflix | -8 | -| Jason Lowe | jlowe | NVIDIA | -6 | -| Jonathan Hung | jhung | LinkedIn | -8 | -| Junping Du | junping_du | Huawei | 0 | -| Kinga Marton | kmarton | Cloudera | +1 | -| Konstantinos Karanasos | kkaranasos | Microsoft | -8 | -| Luciano Resende | lresende | Apple | -8 | -| Manikandan R | mani | Cloudera | +5.5 | -| Peter Bacsko | pbacsko | Cloudera | +1 | -| Rainie Li | rainieli | Pinterest | -8 | -| Subramaniam Krishnan | subru | Microsoft | -8 | -| Sunil Govindan | sunilg | Cloudera | -8 | -| Tao Yang | taoyang | Alibaba | +8 | -| Tingyao Huang | tingyao | TrendMicro | +8 | -| Vinod Kumar Vavilapalli | vinodkv | Cloudera | +5.5 | -| Wangda Tan | wangda | Waii | -8 | -| Wei-Chiu Chuang | weichiu | Cloudera | -8 | -| Weiwei Yang | wwei | Apple | -8 | -| Wilfred Spiegelenburg | wilfreds | Cloudera | +11 | -| Yu Teng Chen | yuteng | NTCU | +8 | - -## Committer - -> 以下列表不包括 PMC 成员 - -| 名称 | ApacheID | 组织 | 时区
(UTC) | -|----------------|---------------|-------------|---------------| -| Chia-Ping Tsai | chia7712 | Is-Land | +8 | -| Li Gao | ligao | Databricks | -8 | -| PoAn Yang | payang | | +8 | -| Hsuan Zong Wu | samhxwu | | +8 | -| Ted Lin | steinsgateted | NCKU | +8 | -| Qi Zhu | zhuqi | Cloudera | +8 | - -## 成为一个 Committer - -Committers 是对项目存储库具有写入权限的社区成员, -即他们可以自己修改代码并接受其他人对所有 YuniKorn 存储库的贡献。 -PMC 根据各种考虑对候选人进行投票: - -- 代码贡献 - - 一致的代码贡献 - - 优化 CI/CD 管道 - - 帮助进行代码审查 - - 测试和验证候选版本 - - 性能调优及相关工具开发 - - 提出改进建议 - -- 非代码贡献 - - 参与社区活动,如会议、聚会等。 - - 提供反馈、报告问题并参与路线图讨论 - - 项目发布帮助 - - 改进项目文档 - - 帮助项目采用 - - 与其他项目集成,扩展用例 - -contributor 或非 contributor 都可以成为 committer,社区非常感谢代码或非代码贡献。 - -## 成为 PMC 成员 - -PMC 为 Project Management Committee。 -它负责项目管理、治理并确保项目可以在 [Apache Way](https://www.apache.org/theapacheway/) 下运行。 -委员会根据 PMC 成员的投票做出决定。 -PMC 成员有权对各种事情进行有约束力的投票,例如项目发布、添加新的提交者或 PMC 成员等。 - -在成为 PMC 成员之前,贡献者必须先成为提交者。 -提交者何时有资格被添加到 PMC 没有严格的规定。 -管理委员会根据每个提交者的参与和影响做出决定。 -一般来说,对项目做出持续的代码或非代码贡献的贡献者应被视为 PMC 候选人。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/community/release_procedure.md b/i18n/zh-cn/docusaurus-plugin-content-pages/community/release_procedure.md deleted file mode 100644 index 5af7df4a5b9..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/community/release_procedure.md +++ /dev/null @@ -1,339 +0,0 @@ ---- -id: release_procedure -title: 发布流程 ---- - - - -# YuniKorn 发布流程 - -[发布存储库](https://github.com/apache/yunikorn-release) 包含了 Apache YuniKorn 创建发行版本/发布(为了区分一些释义以及词语概念的混淆,下文暂在一些描述中以原始名称 release 进行说明)的代码和配置。 -我们需要在开始发布流程之前克隆存储库并签出主分支。 -即使之前已经发布过该版本,也请确保签出最新的发布内容,因为代码和/或配置可能已更改。 - -相关说明和工具会遵守ASF的[发布政策](http://www.apache.org/legal/release-policy.html)。 - -* [发布流程](#发布流程) -* [流程步骤](#流程步骤) - * [打标签并更新发布版本](#打标签并更新发布版本) - * [更新修改日志](#更新修改日志) - * [运行发布工具](#运行发布工具) - * [创建签名](#创建签名) - * [创建Checksum](#创建checksum) - * [上传候选发布文件](#上传候选发布文件) - * [开始投票流程](#开始投票流程) - * [发布](#发布) - * [发布 Docker 镜像](#发布-docker-镜像) - * [发布 Helm Charts](#发布-helm-charts) - * [更新网站](#更新网站) - * [清理](#清理) - * [创建 GIT 发布](#创建-git-发布) - * [验证发布](#验证发布) -* [为新发布更新网站](#为新发布更新网站) - * [更新文档版本](#更新文档版本) - * [发布公告](#发布公告) - * [更新下载页面](#更新下载页面) -* [签名您的第一个发布](#签名您的第一个发布) - * [生成密钥](#生成密钥) - * [将签名添加到项目KEYS文件中](#将签名添加到项目keys文件中) - -## 发布流程 -简化的发布流程: -1. 在所有 git 存储库中为目标 release 的版本创建一个发布分支,比如 `branch-0.8` -2. 这个发布版本只能通过修复测试失败问题和错误来趋于稳定 -3. 给新版本的更新发布打标签,以作为准备发布的候选版本,例如给 RC1 标记为 `v0.8.0-1` -4. 更新 CHANGELOG (以后统称为修改日志) -5. 配置[release-configs.json](https://github.com/apache/yunikorn-release/tree/master/tools/release-configs.json) -6. 运行脚本[build-release.py](https://github.com/apache/yunikorn-release/tree/master/tools/build-release.py) 生成源代码压缩包、checksum 和签名。 -7. 投票和发布候选版本 - -## 流程步骤 -### 打标签并更新发布版本 -分支和标签可以——并且在大多数情况下会——更改 go mod 文件。 -分支是发布准备阶段的一部分,通常在发布过程开始之前的某个时间发生。 -一个 release 在开始发布流程之前,需要在 git 中给它打上标签。 -可以查看 [YUNIKORN-358](https://issues.apache.org/jira/browse/YUNIKORN-358) 或者 [YUNIKORN-1004](https://issues.apache.org/jira/browse/YUNIKORN-1004),他们可以作为例子进行参考。 -release 的候选版号本应该用 release 的版本号和候选构建数进行标记。 -例如,用于构建 0.8.0 RC2 的文件应该标记为 `v0.8.0-2`,并在 GitHub 中创建该 release。 -一旦 release 完成,应该为 `v0.8.0` 创建 git 的标签和 GitHub 的 releases,指向相同的提交。 -在任何情况下,都不应删除或移动现有的标签。这将打破下游用户的 golang 依赖解析。 - -标签处理是一个多步骤的过程,所有操作都需在将要发布的分支上完成,例如 `branch-0.8` : -1. 给 web 和 scheduler-interface 项目打上发布标签。 -2. 使用 `go get github.com/apache/yunikorn-scheduler-interface` 更新 core 项目中的 `go.mod` 文件,然后添加标签并提交更改。 -3. 使用 `go get github.com/apache/yunikorn-scheduler-interface` 和 `go get github.com/apache/yunikorn-core` 更新 shim 项目中的 `go.mod` 文件。之后再添加标签并提交更改。 -4. 在yunikorn的发布存储库中新建一个分支,然后在[Chart.yaml](https://github.com/apache/yunikorn-release/tree/master/helm-charts/yunikorn/Chart.yaml) 中设置正确的chart版本并创建标签。 - -### 更新修改日志 -我们为每次 release 内的发布文件里添加了一个[修改日志](https://github.com/apache/yunikorn-release/tree/master/release-top-level-artifacts/CHANGELOG)。 -修改日志应包含版本中修复的 jiras 列表。 -我们可以按照以下步骤生成列表: -- 转到 [jira发布页面](https://issues.apache.org/jira/projects/YUNIKORN?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&status=released-unreleased) -- 点击即将发布的版本,例如 `0.8.0` -- 点击页面顶部的 `Release Notes`(发布说明) 链接 -- 单击 `Configure Release Notes`(配置发布说明)按钮 -- 选择样式 `Text` 并点击 `create` -- 滚动到页面底部并复制文本区域的内容并更新 ../release-top-level-artifacts 目录中的修改日志文件。 - -### 运行发布工具 -我们已经编写了一个工具来处理大部分的发布任务。 -该工具需要在运行前更新一个简单的 [json](https://github.com/apache/yunikorn-release/tree/master/tools/release-configs.json) 输入文件。 -此配置指向当前的发布标签。它只会更新每个存储库的标签。 - -该工具在标准的Python3之外有一项要求:[GitPython](https://gitpython.readthedocs.io/en/stable/intro.html)。 -请确保您已通过运行 `pip install gitpython` 来安装它。 - -运行工具: -```shell script -python3 build-release.py -``` -如果您想使用 GPG 密钥自动签署版本,请使用以下命令运行该工具: -```shell script -python3 build-release.py --sign <邮件地址> -``` - -#### 创建签名 -如果您有带有 _pinentry_ 程序设置的 GPG,您可以使用发布工具自动签署发布。 -在 MacOSX 上,如果您使用钥匙串作为秘钥,这将自动设置。 -有关更多的详情,请查看 [GnuPG 工具 wiki](https://wiki.archlinux.org/index.php/GnuPG),特别是 [pinentry](https://wiki.archlinux.org/index.php/GnuPG#pinentry) 章节。 - -使用 `--sign <邮件地址>` 选项来运行发布工具以自动签署发布。 - -为工具生成的文件手动创建签名: -```shell script -gpg --local-user <邮件地址> --armor --output apache-yunikorn-0.8.0-src.tar.gz.asc --detach-sig apache-yunikorn-0.8.0-src.tar.gz -``` -这将在文件中创建签名:`apache-yunikorn-0.8.0-src.tar.gz.asc` -使用以下命令验证签名是否正确: -```shell script -gpg --verify apache-yunikorn-0.8.0-src.tar.gz.asc apache-yunikorn-0.8.0-src.tar.gz -``` - -#### 创建Checksum -这一步包含在源tar包生成后的发布内容中,如果使用发布工具可以跳过这一步。 -```shell script -shasum -a 512 apache-yunikorn-0.8.0-src.tar.gz > apache-yunikorn-0.8.0-src.tar.gz.sha512 -``` -这将在文件中创建 checksum : `apache-yunikorn-0.8.0-src.tar.gz.sha512` -使用以下命令验证 checksum 是否正确: -```shell script -shasum -a 512 -c apache-yunikorn-0.8.0-src.tar.gz.sha512 -``` - -### 上传候选发布文件 -发布的文件由三个部分组成: -- 源压缩包 -- 签名文件 -- checksum文件 - -三个文件都需要上传到:`https://dist.apache.org/repos/dist/dev/yunikorn/` - -根据版本创建发布目录,例如 `0.8.0`,将这三个文件添加到目录中,随后提交更改。 - -如果您还没有这样做,请确保 [添加您的签名](#将签名添加到项目keys文件中) 到 KEYS 文件。 -不要从保存在此处的文件中删除任何密钥,这是为了方便验证旧的版本。 - -注意:您需要安装 subversion 才能访问此 repo(使用您的 apache ID)。为方便起见,您可以使用任何 SVN 客户端,例如 svnX。 - -### 开始投票流程 -根据 Apache [发布批准文档](http://www.apache.org/legal/release-policy.html#release-approval) -投票流程必须在 `dev@yunikorn.apache.org` 上创建,并运行至少72小时。 -需要至少三个 +1 票,而且 +1 票要多于 -1 票。 - -### 发布 -一旦投票通过,将发布的文件从暂存区移动到发布位置 `https://dist.apache.org/repos/dist/release/yunikorn/`。 -一旦移动到这个空间,内容将自动同步到 `https://downloads.apache.org/yunikorn/`,它必须作为所有发布文件的最终位置。 - -可以阅读 [分布式服务](https://apache.org/history/mirror-history.html) 来了解更多有关源代码的内容。 - - -这将会在发布区暂时为我们提供两个版本。 -这是允许启动镜像同步过程并允许更新下载页面的必要条件。 -在 [清理](#清理) 章节中会说明如何在更新网站后对旧的版本进行清理。 - -#### 发布 Docker 镜像 -我们应该使用标准构建过程来构建镜像。 -在 `web` 和 `k8shim` 存储库中运行 `make image` 以生成所需的三个镜像(web、调度器和准入控制器): -```shell script -VERSION=0.8.0; make image -``` - -如果您有权访问 Apache docker hub YuniKorn 容器,Make 也可用于构建和推送映像。 -使用发布版本号作为标签将最新的 docker 镜像推送到 apache docker hub。 -需要确保 docker 映像是基于特定的 SHA 构建的。 -```shell script -VERSION=0.8.0; DOCKER_USERNAME=<用户名>; DOCKER_PASSWORD=<密码>; make push -``` -最后向 `dev@yunikorn.apache.org` 邮件列表发布一个公告邮件。 - -#### 发布 Helm Charts -此步骤是发布工具的一部分,如果使用了发布工具则可以跳过这个打包步骤。 - -如果发布工具 **未** 使用 `Chart.yaml`, 那么 `values.yaml` 必须手动更新。 -另一种选择是像发布工具一样针对生成的源目录运行 helm 脚本: -```shell script -helm package --sign --key ${您的key名称} --keyring ${path/to/keyring.secret} staging/<发布文件夹>/helm-charts/yunikorn --destination staging/ -``` -签署 helm 包需要一个旧的 PGP keyring。 PGP v2 keyring 必须转换为旧的格式。 -想了解更多的信息,请查看 [Helm 文档](https://helm.sh/docs/topics/provenance/)。 -Helm charts 应在发布时签名。 -与源代码 tar 包签名相反,对 helm 图表进行签名需要手动输入密钥密码。 - -helm 打包会生成两个文件: -- helm 打包文件:例如 `yunikorn-0.8.0.tgz` -- 出处或签名文件:例如 `yunikorn-0.8.0.tgz.prov` -这两个文件都应附加到发布存储库的 [创建GIT发布](#创建GIT发布) 中。 - -最后一步是使用新的发布版本更新 `gh-pages` 分支中的 [index.yaml](https://github.com/apache/yunikorn-release/blob/gh-pages/index.yaml) 文件。 -index.yaml 文件中提到的 `摘要` 是由工具(未签名的包)打印或存储在出处文件中的摘要。 -我们可以使用以下方法手动生成: -```shell script -shasum -a 256 yunikorn-0.8.0.tgz -``` - -注意:不要使用 `helm repo index` 命令来更新 `index.yaml` 文件。该命令不能很好地处理存储在 `index.yaml` 文件中的增强信息。 -请手动更新文件。 - -#### 更新网站 -- 根据 `docs` 目录中的最新内容,在 YuniKorn 网站上创建一个新的文档版本。 - 请参考[如下步骤](#更新文档版本)来了解如何创建新的文档版本。 -- 从网站上的下载页面下创建发布公告的引用链接。 - 发布公告是一个基于版本号的 markdown 文件: `0.8.0.md`。 - 如何创建[发布公告](#发布公告)的章节解释了相关的内容以及添加文件的位置。 -- 按照[此步骤](#更新下载页面)更新网站的[下载页面](/community/download)。 - -这个网站可以,而且很可能会包含一个公告栏。 -这个公告栏是源代码树的根目录中 `docusaurus.config.js` 文件的一部分。 -我们需要更新公告栏到正确的 release。 - -#### 清理 -注意:此步骤应在网站更新后执行,因为下载链接会进行更改。 - -发布区域中应该只有一个发布信息,即最新的发布。 -已在发布区域中的任何发布信息都将自动复制到存档中。 -旧的发布信息应直接从存档下载,而不是从发布区域下载。 - -发布信息需要在两个位置进行清理: -* 通过删除旧的候选发布目录,从 _dev_ 区域中删除新发布的版本。 - 请参阅 [候选发布位置](#上传候选发布文件) 来查看相关位置 -* 通过删除旧发布目录从 _发布_ 区域中删除非当前的发布信息。 - 请参见 [发布位置](#发布) 来查看相关位置 - -#### 创建 GIT 发布 -在 GIT 存储库中,通过添加的 git 标签来创建发布,并最终完成发布流程。 -对所有五个存储库(core、k8shim、web、scheduler-interface 和 release)都重复这些步骤: -- 转到 `tags` 页面 -- 单击要发布的页面右侧的 `...` ,从下拉列表中选择 `Create Release` -- 更新名称和说明 -- 添加打包好的 helm chart 文件(仅限 yunikorn-release 存储库) -- 单击 `Publish Release` 以完成步骤 - -### 验证发布 -在整个流程完成后,我们需要验证网站上的文档。 -检查发布的文件是否可以从下载页面进行下载。 - -## 为新发布更新网站 -发布新版本需要您在本地安装 yarn。 - -先决条件: -* 该 release 必须已从发布流程获得批准。 -* 源存档文件和签名必须已上传到 Apache 对应的位置。 -* docker 公共镜像必须已推送到 Apache docker hub。 - -打开一个PR,并将下面的所有更改提交到 **master** 分支,一旦自动构建完成,新的文档就会出现在网站上。 - -### 更新文档版本 -文档的版本控制使用简单的 **主要版本.次要版本.补丁版本** 这种 semver(语义化的版本号)形式定义发布版本号。 -这意味着没有字母,候选发布标签或类似的东西: -```shell script -yarn release 0.8.0 -``` -该命令将对当前 `docs` 目录中的所有文档打快照,并将所有文件复制到另一个新目录 `versioned_docs` 下,例如 `versioned_docs/version-0.8.0` 。 -类似的复制过程会在 `versioned_sidebars` 下生成对应文档版本的侧边栏。 - -这个过程还会更新 `version.json` 文件,并将添加一行新的发布版本。 - -### 发布公告 -发布公告是一个添加到 `src/pages/release-announce` 目录下的静态 Markdown 文件。 -文件名与发布的 semver 简化版本号相同: -``` -src/pages/release-announce/0.8.0.md -``` -该页面采用 Markdown 格式,应遵循现有页面的示例: -* id和标题定义(docusaurus 语法) -* Apache license -* 如下的标题 - * 发布的概述(2级标题) - * 重点内容(2级标题) - 在第3级标题说明各个重点 - * 社区更新(2级标题) - -### 更新下载页面 -下载页面要包含指定到 Apache 源代码下载、签名等的链接。 -页面上的表格有一个特定的布局,在完成 docusaurus 构建后,该布局会被正确地呈现。 -请不要更改表格中的发布条目的布局。 - -第一步是将 `最新版本` 行更新为正确的版本。 -第二步是更新表:从表中删除最后一行。 -复制表格的第一行并更改链接和详细信息以反映新的发布详情。 -必须更新所有的链接: -* 3个用于下载的内容(源码tar、checksum 和签名) -* 3个用于docker的镜像(scheduler, admission-controller 和 web) -* 1个发布公告,使用 `/release-announce/0.8.0` 形式的链接 - -对于第二行,更新源码tar、checksum 和签名的下载链接。 - -发布的链接必须遵循以下规则: -* 页面上的第一个下载链接 **必须** 只能使用源码tar包的镜像解析链接。 -* 签名和 checksum 链接 **必须** 指向发布地址。 -* 非当前版本 **必须** 使用存档链接:`https://archive.apache.org/dist/yunikorn/` 用于 tar 包、签名和checksum。 - -表中应保留有限的三或四个版本以供直接访问。 -表中未提及的旧版本仍可通过页面底部的存档链接访问,无需参考。 - -## 签名您的第一个发布 -如果您之前没有对任何版本进行签名,请阅读文档以 [生成签名密钥](https://infra.apache.org/openpgp.html#generate-key) -请按照以下步骤添加可用于签名的密钥。 - -### 生成密钥 -生成新的 PGP 密钥(如果您已有 Apache 链接密钥,请跳过此步骤): -```shell script -gpg --gen-key -``` -使用您的全名和 Apache 邮件地址填写请求的信息。 - -将导出的密钥上传到像 `https://pgp.mit.edu/` 这样的公钥服务器。 -```shell script -gpg --export --armor <邮件地址> -``` - -将 fingerprint 上传到 apache 服务器:`https://id.apache.org/`。 -```shell script -gpg --fingerprint <邮件地址> -``` - -### 将签名添加到项目KEYS文件中 -只有当这是使用特定密钥签名的第一个发布版本时才需要。 -可以在此文档中找到更多详细信息:[签署版本](https://infra.apache.org/release-signing.html#keys-policy) -```shell script -(gpg --list-sigs <邮件地址> && gpg --armor --export <邮件地址>) >> MY_KEY -``` -将生成文件的内容添加到 `https://dist.apache.org/repos/dist/release/yunikorn/KEYS` 现有 KEYS 列表中。 -切勿从此列表中删除密钥! - -注意:您需要安装 subversion 才能访问此 repo(使用您的 apache ID)。为方便起见,您可以使用任何 SVN 客户端,例如 svnX。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/community/reporting_issues.md b/i18n/zh-cn/docusaurus-plugin-content-pages/community/reporting_issues.md deleted file mode 100644 index 76ad350fd7b..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/community/reporting_issues.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -id: reporting_issues -title: 报告问题 ---- - - - -# 报告问题 - -## 报告安全问题 -YuniKorn 社区非常关心安全问题,并将积极解决任何安全问题作为重中之重。 -我们遵循 Apache 安全指南来处理安全问题,请参阅 Apache 文档关于 [处理安全问题](https://www.apache.org/security/)。 -如果您发现任何安全问题,请将漏洞报告发送至 security@apache.org,YuniKorn 安全团队将立即评估问题并与报告者一起制定修复计划。 -在与安全团队合作之前,请不要将问题透露给任何公共论坛。 - -## 对于 YuniKorn 用户 -如果您对 YuniKorn 操作有任何疑问,请遵循以下指南: - -如果您在设置、配置或在其他不符合您期望的行为方面遇到问题时,请加入用户邮件列表并在该论坛中提问。 -有关邮件列表的信息,请参见 [YuniKorn 网页](https://yunikorn.apache.org/zh-cn/community/get_involved)。 -您也可以向 YuniKorn slack 频道寻求帮助,查看网页了解如何加入的详细信息。 -如果您在代码或文档中有需要修复的错误,请按照下面的 [归档 JIRA](#为-YuniKorn-问题提交-JIRA) 中的步骤进行操作。 - -Apache YuniKorn 项目使用 JIRA 来跟踪所有问题。 -这些包括: -1. 添加新功能 -2. 改进现有功能 -3. 报告代码库中需要修复的错误 - -如果您对在 JIRA 中跟踪开发问题感兴趣,可以浏览这个[链接](https://issues.apache.org/jira/projects/YUNIKORN)。 - -## 为 YuniKorn 问题提交 JIRA -请转到 Apache JIRA 页面来提交您的问题。 - -请确保项目设置为 YuniKorn。需要根据您的分析或请求适当设置问题类型字段: -* (Bug)漏洞 -* (New Feature)新功能 -* (Improvement)改进 -* (Test)测试 -* (Wish)希望 -* (Task)任务 - -对于摘要,请提供详细的标题,例如 _K8 pod not scheduled in an empty cluster_ 而不仅仅是 _YuniKorn scheduling failed_。 - -如果您已将问题分到特定组件,请设置组件字段: - -| 组件 | 描述 | -|---------------------|---------------------| -| build | 项目构建、构建脚本和 git 问题 | -| core - common | 核心调度器的公共代码,如资源 | -| core - scheduler | 核心调度问题 | -| documentation | 文档修复和增强 | -| scheduler-interface | 调度器接口规范 | -| security | 安全相关问题(加密、授权和身份验证) | -| shim - kubernetes | K8shim 问题 | -| shim - yarn | Hadoop YARN shim 问题 | -| test - smoke | 冒烟测试失败 | -| test - unit | 单元测试失败 | -| webapp | 调度器的 Web UI | -| website | 网站内容(不包括文档) | - -影响版本字段可以设置为您发现错误的YuniKorn的最早版本。 -如果您不确定,则将其留空。 - -:::note -如果您认为对于还不熟悉该项目的人来说这是一个好问题,您可以将 JIRA 的标签设置为 *newbie*。 -::: - -如果您是打算修复该错误的开发人员,请将您的 JIRA ID 放在 Assignee 字段中。 -请注意,您需要在 Apache YuniKorn 的贡献者列表中才能分配 JIRA ticket。 -如果您还没有被添加到列表中,请发送电子邮件到 [dev@yunikorn.apache.org](mailto:dev@yunikorn.apache.org) 邮件列表或在 jira 的评论中请求它。 - -请在描述字段中填写尽可能多的详细信息。 -这需要包括您的配置更改、集群大小和 YuniKorn 版本。 -任何有助于复制您应该添加的问题的相关代码或配置。 - -对于错误报告:问题的简短再现将非常受欢迎。 -如果您有日志,则日志的特定部分要带有错误消息或堆栈跟踪。 -附加整个日志可能很有用。 -如果您已经尝试调试问题,请描述您已经完成的步骤。 -即使结果是您无法重现该问题。 - -对于新功能请求,它可能包括设计文档。 -如果您没有,或者这只是一个通用请求,请与我们合作设计您的功能并实现它。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/community/roadmap.md b/i18n/zh-cn/docusaurus-plugin-content-pages/community/roadmap.md deleted file mode 100644 index 14c9086ab24..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/community/roadmap.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -id: roadmap -title: 路线图 ---- - - - -# Kubernetes 版本支持 -支持的 Kubernetes 版本和 Kubernetes 依赖项将在开发周期中进行选择和最终确定。 -目前的构建依赖版本: 1.27 - -# 下一个发布研发内容 -发布详情: -- 版本:1.5.0 -- 目标发布日期:2024 年 2 月/3 月 -- 发布负责人:尚未决定 -- 开发状态:[问题跟踪器](https://issues.apache.org/jira/issues/?filter=12348416) - -计划的主要功能: -- [YUNIKORN-970](https://issues.apache.org/jira/browse/YUNIKORN-970) 将队列指标改为可标记的 -- [YUNIKORN-1544](https://issues.apache.org/jira/browse/YUNIKORN-1544) 使用者与群组配额实施 - 阶段 2 -- [YUNIKORN-2099](https://issues.apache.org/jira/browse/YUNIKORN-2099) [Umbrella] 简化 K8shim -- [YUNIKORN-2115](https://issues.apache.org/jira/browse/YUNIKORN-2125) [Umbrella] 应用程式追踪历史 - 阶段 2 -- [YUNIKORN-1362](https://issues.apache.org/jira/browse/YUNIKORN-1362) UI 中的节点过滤 -- [YUNIKORN-1727](https://issues.apache.org/jira/browse/YUNIKORN-1727) 建置资讯扩展 -- [YUNIKORN-1922](https://issues.apache.org/jira/browse/YUNIKORN-1922) 在网页UI中显示待处理的资源 -- [YUNIKORN-2140](https://issues.apache.org/jira/browse/YUNIKORN-2140) Web UI: 资源显示重制 -- [no jira yet] 在 web UI 中显示抢占讯息 - -# 未来发展:长期的目标 -- [YUNIKORN-22](https://issues.apache.org/jira/browse/YUNIKORN-22) 支援节点分区 -- [YUNIKORN-1728](https://issues.apache.org/jira/browse/YUNIKORN-1728) 支持队列最大应用程式及资源百分比 -- 队列类型从叶节点变为父节点,反之亦然 -- 应用程式的队列间移动 -- 压缩队列配置 (configmap 1MB 限制) -- 可重复的构建 -- FIPS 构建 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/img b/i18n/zh-cn/docusaurus-plugin-content-pages/img deleted file mode 120000 index 13a513d9176..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/img +++ /dev/null @@ -1 +0,0 @@ -../../../static/img \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/index.js b/i18n/zh-cn/docusaurus-plugin-content-pages/index.js deleted file mode 100644 index 85ebfb4e58d..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/index.js +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. -*/ - -import React from 'react'; -import clsx from 'clsx'; -import Layout from '@theme/Layout'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import styles from './styles.module.css'; - -const features = [ - { - title: <>调度能力, - imageUrl: './img/resource-scheduling.png', - description: ( - <> - 内置全面的调度功能,包括层次队列、 - 跨队列的资源公平性、作业排序 (FIFO/FAIR)、 - 可插拔节点排序策略、抢占等。 - - ), - }, - { - title: <>K8s 资源调度器, - imageUrl: './img/support-k8s.png', - description: ( - <> - 完全兼容 K8s,是默认 K8s 调度的替代方案,但功能更强大。 - 对现有的 K8s 应用程序完全透明。 - - ), - }, - { - title: <>云原生, - imageUrl: './img/cloud-native.png', - description: ( - <> - 支持本地和云端用例。 - 在云上运行时,它与弹性伸缩控制器共同协作,以带来最大的资源弹性和更好的吞吐量。 - - ), - }, -]; - -const why = [ - { - title: <>分层资源队列, - imageUrl: './img/why-hierarchical-queue.svg', - description: ( - <> - 对不同租户的资源配额进行细粒度控制,轻松映射到您的组织结构。 - 为队列的最小/最大资源提供了超额分配的功能,同时确保了有保障的资源。 - - ), - }, - { - title: <>应用感知调度, - imageUrl: './img/why-app.svg', - description: ( - <> - 识别用户、应用程序、队列。 - 应用程序按特定顺序进行排队和调度。 - 根据资源公平性、提交时间和优先级应用排序。 - 您可以获得更可预测的调度结果。 - - ), - }, - { - title: <>效率和成本节约, - imageUrl: './img/why-save-cost.svg', - description: ( - <> - 针对云进行了优化,并尽可能地适应弹性伸缩。 - Gang Scheduling 减少了资源碎片,并主动触发扩容。 - Bin-packing 在云上运行时可以改变使用曲线,并降低成本。 - - ), - }, - { - title: <>中央管理控制台, - imageUrl: './img/why-console.svg', - description: ( - <> - 不再丢失跟踪租户的资源使用情况! - YuniKorn 提供中央管理 UI 和一站式看板来跟踪集群、队列和应用程序的资源利用率。 - 让我们开始为您的团队规划和监控资源! - - ), - }, -]; - -function Home() { - const context = useDocusaurusContext(); - const {siteConfig = {}} = context; - return ( - -
-
-
-
-

{siteConfig.title}

-

释放在 Kubernetes 上运行大数据和机器学习资源调度的力量!

- -
-
- YuniKorn logo -
-
-
-
-
- {features && features.length && ( -
-
-
- {features.map(({imageUrl, title, description}, idx) => ( -
- {imageUrl && ( -
- {title.toString()}/ -
- )} -

{title}

-

{description}

-
- ))} -
-
-
- )} -
-

☺ 为什么选YuniKorn?

- {why.map(({imageUrl, title, description}) => ( -
- {title.toString()}/ -

{title}

-

{description}

-
- ))} -

了解更多 >>>

-
-
-
- ); -} - -export default Home; diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.10.0.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.10.0.md deleted file mode 100644 index ffcc2619864..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.10.0.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -id: rn-0.10.0 -title: 发布公告 v0.10.0 ---- - - -# 发布公告 v0.10.0 -我们非常高兴地宣布 Apache YuniKorn (Incubating) 社区已投票发布 0.10.0。Apache YuniKorn (Incubating) 是一个独立的资源调度器,旨在管理和调度容器编排框架上的大数据工作负载,支持本地和云端的用例。 - -此版本中添加的显著功能是 Gang Scheduling,YuniKorn 现在可以在 Kubernetes 上运行应用程序时提供 gang scheduling 调度功能。除此之外,此版本还包括各种错误修复和改进。 - -## 概述 -Apache YuniKorn (Incubating) 社区在此版本中修复了 187 个 JIRA 问题:[YuniKorn 在 0.10.0 中解决的 jira 问题](https://issues.apache.org/jira/issues/?filter=12349466)。 - -发布负责人: Tao Yang - -发布时间: 2021-04-09 - -## 主要更新 - -### 支持的 Kubernetes 版本 -从此版本开始,支持的 Kubernetes 版本已更新为 1.16.x、1.17.x 和 1.18.x。(早期版本支持 1.13.x、1.14.x 和 1.15.x)YuniKorn 支持矩阵主要支持 3 个主要的 Kubernetes 版本。 - -### Gang Scheduling -在这个版本中,YuniKorn 开始支持 Gang Scheduling。用户可以将 Gang Scheduling 应用于需要 gang scheduling 语义的应用,如 Spark、Tensorflow、Pytorch 等。YuniKorn 主动为 gang scheduling 应用预留资源,它与 cluster-autoscaler 配合使用更高效。初始的支持已经在 Spark 上进行了很好的测试,它可以与 K8s 上的原生 Spark 或 Spark K8s operator 一起使用。有关如何启用和使用 Gang Scheduling 的更多信息,请阅读 [此处](/docs/user_guide/gang_scheduling) 的文档。 - -### 简化调度器核心中的逻辑 -社区对调度程序核心进行了重大的代码重构,可以在 [YUNIKORN-317](https://issues.apache.org/jira/browse/YUNIKORN-317) 内进行跟踪。这种重构将缓存和调度器模块合二为一,消除了代码中的大量复杂性,提高了核心调度逻辑的效率。因此,它更易于阅读并减轻了维护工作。 - -### 应用程序跟踪 API 和 CRD 第一阶段 -此版本引入了应用程序跟踪 API 和 K8s 自定义资源定义 (CRD),借以进一步改善用户体验。应用程序 operator/作业服务器将使用 CRD 与 YuniKorn 交互,以提供更好的应用程序生命周期管理。第一阶段定义了通用协议消息和 CRD 对象格式。 - -### Web UI 翻新 -社区对 Web UI 进行了一些可用性改进,包括重新设计的 Web UI 布局、调整外观以提供更好的用户体验、修复错误等。 - -## 社区 -Apache YuniKorn 社区很高兴欢迎新的 committer Julia Kinga Marton 和 Tingyao Huang。我们希望看到更多的提交者加入社区并帮助塑造项目。在过去的几个月里,我们会继续在2个不同的时区举行两周一次的社区会议、临时会议、线下渠道讨论。我们的社区将继续开放给各位。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.11.0.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.11.0.md deleted file mode 100644 index 2631a5c7605..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.11.0.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -id: rn-0.11.0 -title: 发布公告 v0.11.0 ---- - - -# 发布公告 v0.11.0 -我们非常高兴地宣布 Apache YuniKorn (Incubating) 社区已投票发布 0.11.0。Apache YuniKorn (Incubating) 是一个独立的资源调度器,旨在管理和调度容器编排框架(如 Kubernetes)上的大数据工作负载,支持本地和云端的用例。 -此版本有几个 REST API、UI 可用性和联邦调度的改进。 - -## 概述 -Apache YuniKorn (Incubating)社区在此版本中修复了 110 多个 JIRA 问题:[YuniKorn 在 0.11.0 中解决的 jira 问题](https://issues.apache.org/jira/issues/?filter=12350521)。 - -发布负责人: Kinga Marton - -发布日期: 2021-08-18 - -## 主要更新 - -### 支持的 Kubernetes 版本 -在此版本中,支持的 Kubernetes 版本已更新为 1.17.x、1.18.x 和 1.19.x。(早期版本支持 1.16.x、1.17.x 和 1.18.x)YuniKorn 支持矩阵主要支持 3 个主要的 Kubernetes 版本。 - -### Gang scheduling 增强功能 -社区已对 [Gang scheduling](http://yunikorn.apache.org/zh-cn/docs/user_guide/gang_scheduling) 功能进行了进一步改进。[Gang scheduling 模式](http://yunikorn.apache.org/zh-cn/docs/user_guide/gang_scheduling#gang-scheduling-styles -) 现在可以为每个应用程序配置,soft 或者 hard。这允许用户自定义如何处理预订超时的行为。还有许多增强功能可以改善占位 pod 的生命周期管理,使清理更加健壮和可靠。更多细节可以在 [YUNIKORN-553](https://issues.apache.org/jira/browse/YUNIKORN-553) 中找到。 - -### Spark operator 集成 -通过利用 YuniKorn 的应用管理框架,现在它可以更好地与 Spark operator 集成。YuniKorn 监听 spark 的 CRD 资源并在必要时做出反应。在 K8s 上使用 YuniKorn 和 Spark operator 是完全透明的,不需要额外的配置。此功能已准备好用于生产。更多细节可以在 [YUNIKORN-558](https://issues.apache.org/jira/browse/YUNIKORN-558) 中找到。 - -### 调度器指标增强 -YuniKorn 通过 Prometheus 开放了核心的 [调度指标](http://yunikorn.apache.org/zh-cn/docs/next/performance/metrics),在这个版本中,一些重要的指标如 allocating_latency_seconds,long_pending_apps 被添加到系统中,这样集群管理员可以创建更多警报来监控系统健康状况。我们对现有指标(例如应用程序/队列)进行了更多增强,使其更具可读性和组织性。您可以在 [YUNIKORN-3](https://issues.apache.org/jira/browse/YUNIKORN-3) 中找到更多详细信息。 - -### 用户/组解析 -通过在 [YUNIKORN-649](https://issues.apache.org/jira/browse/YUNIKORN-649) 中完成的工作,现在用户可以定义如何检索每个应用程序和 pod 的用户/组身份。这是通过可配置的环境变量 USER_LABEL_KEY 来完成的,因此用户可以指定 YuniKorn 将使用哪个标签来检索用户身份。该文档可以在 [这里](http://yunikorn.apache.org/zh-cn/docs/next/user_guide/usergroup_resolution) 找到。 - -### Web UI 和 REST API 可用性增强 -社区对 Web UI 进行了一些可用性改进,以提供更好的用户体验。UI 已被简化,借以在应用程序/节点页面中显示有用的数据,一些可用性错误也已得到修复。在此版本中,引入了一些新的 REST API ,使获取每个分区/队列信息成为可能。您可以在 [此处](http://yunikorn.apache.org/docs/api/scheduler) 找到完整的接口列表。 - -## 社区 -Apache YuniKorn 社区很高兴欢迎新的提交者 Manikandan R 和新的 PPMC 成员 Kinga Marton。我们希望看到更多的提交者加入社区并帮助塑造项目。在过去的几个月里,我们会继续在2个不同的时区举行两周一次的社区会议、临时会议、线下渠道讨论。我们的社区将继续开放给各位。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.12.1.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.12.1.md deleted file mode 100644 index dd776baaa32..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.12.1.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -id: rn-0.12.1 -title: 发布公告 v0.12.1 ---- - - -# 发布公告 v0.12.1 -我们很高兴地宣布 Apache YuniKorn (Incubating) 社区已投票发布 0.12.1。 -Apache YuniKorn (Incubating) 是一个独立的资源调度器,旨在管理和调度容器编排框架(如 Kubernetes)上的大数据工作负载,支持本地和云端的用例。 - -## 概述 -Apache YuniKorn (Incubating) 社区在此版本中修复了150个 [JIRA问题](https://issues.apache.org/jira/issues/?filter=12351063)。请注意,由于 Go Modules 系统的技术问题,我们决定跳过 0.12.0 版本并直接转到 0.12.1,其中标记的标签无法更新以指向事后提交。 - -发布负责人: Chaoran Yu - -发布日期: 2021-12-26 - -## 主要更新 - -### 支持的 Kubernetes 版本 -在此版本中,支持的 Kubernetes 版本已更新为 1.19.x、1.20.x 和 1.21.x。(最后一个支持 1.17.x、1.18.x 和 1.19.x 的版本)。YuniKorn 支持矩阵主要支持 3 个主要的 Kubernetes 版本。 - -### 节点排序改进 -YuniKorn 用于对每个容器的调度按需对所有节点进行排序,这导致节点数量增加时性能变慢。我们在该版本使用了优化的数据结构(B-tree),该改进对节点排序性能实现了相当大的改进。 - -### Gang scheduling 增强功能 -改进的测试覆盖率。添加了对节点亲和性的支持。修复了在删除节点期间处理占位时的严重错误。 - -### 日志记录和可观察性改进 -* 通过添加日志、调整现有日志的严重性级别和删除不需要的日志来增强各种组件的日志记录。 -* 添加了对定期或通过 REST 按需获取调度器的完整状态转储的支持,以方便进行故障排除。 -* 改进了调度器的健康检查,以报告异常的分配问题。 - -### 调度器接口改造 -简化了核心和 shim 用于相互通信的调度器接口。大容量消息被分解,以便每条消息包含较小的有效负载并且仅用于特定目的。大多数消息现在在核心和 shim 之间是双向的。 - -### Kubernetes 依赖升级 -K8shim 所依赖的 Kubernetes 版本已经从 1.16 升级到 1.20。这为支持 Kubernetes 的未来版本铺平了道路。作为这项工作的结果,谓词逻辑已使用调度框架重写。 - -### 最新的性能基准测试结果 -我们很高兴发布使用 Kubemark 的最新代码库的性能评估结果。YuniKorn 的吞吐量比默认调度器提高了4倍。 - -## 社区 -Apache YuniKorn 社区很高兴地欢迎新的 committer: Craig Condit、Chenya Zhang、Chaoran Yu 和 Chia-Ping Tsai,以及新的导师 Luciano Resende 和 Wei-Chiu Chuang。我们希望看到更多的提交者加入社区并帮助塑造项目。在过去的几个月里,我们会继续在2个不同的时区举行两周一次的社区会议、临时会议、线下渠道讨论。我们的社区将继续开放给各位。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.12.2.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.12.2.md deleted file mode 100644 index 412f4ebc04c..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.12.2.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: rn-0.12.2 -title: 发布公告 v0.12.2 ---- - - -# 发布公告 v0.12.2 -我们很高兴地宣布Apache YuniKorn (Incubating) 社区已投票发布 0.12.2。 -Apache YuniKorn (Incubating) 是一个独立的资源调度器,旨在管理和调度容器编排框架(如 Kubernetes)上的大数据工作负载,用于本地和云端用例。 - -## 概述 -The Apache YuniKorn (Incubating) 社区在此版本中修复了 19 个 [JIRA问题](https://issues.apache.org/jira/issues/?filter=12351270) 。 -0.12.2 版本主要是一个维护版本,目的是为了更好地兼容当前的 Kubernetes 版本。这个版本里还修复了 0.12.1 中发现的影响动态卷使用的关键问题,因此我们敦促 0.12.1 的所有用户进行升级。 - -发布负责人: Craig Condit - -发布日期: 2022-02-03 - -## 主要更新 - -### 支持的 Kubernetes 版本 -在此版本中,添加了对 Kubernetes 1.22.x 和 1.23.x 的支持(最新版本支持 1.19.x、1.20.x 和 1.21.x)。 Apache YuniKorn (Incubating) 尝试支持当前所有的 Kubernetes 版本。 - -### 准入控制器部署从调度器部署中分离 -从 0.12.2 开始,准入控制器现在通过 Helm 显式地管理,而不是从调度程序中临时安装。这将使调度程序的重新启动和未来的升级更加可靠。但是,这确实意味着从低于0.12.2的版本迁移到0.12.2版本或者以上将需要通过 Helm 进行卸载/重新安装。 我们预计 Helm 升级将在未来正常运行。 - -### 移除准入控制器中的 beta API 的使用 -在 0.12.2 中,准入控制器进行了更新,以删除在 Kubernetes 1.22 中抛弃的一些 beta 类型的 Kubernetes API 的使用。现在,新的更新允许我们在所有当前维护的 Kubernetes 版本上进行部署。 - -### 弃用旧的 REST API 服务 - -REST API 已更新为支持指定分区的服务。不采用分区参数的旧版本已被弃用,并将在即将发布的版本中删除: - -- `/ws/v1/queues` 替换为 `/ws/v1/partition/{partitionName}/queues` -- `/ws/v1/apps` 替换为 `/ws/v1/partition/{partitionName}/apps` -- `/ws/v1/nodes` 替换为 `/ws/v1/partition/{partitionName}/nodes` - -## 社区 -Apache YuniKorn (Incubating) 社区很高兴地欢迎新的 committer:Peter Bacsko 和 Yu Teng Chen。我们希望看到更多的提交者加入社区并帮助塑造项目。我们将继续在2个不同的时区举行两周一次的社区会议、临时会议和线下渠道讨论。我们的社区将继续开放给各位。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.8.0.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.8.0.md deleted file mode 100644 index 9a1923d04e4..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.8.0.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -id: rn-0.8.0 -title: 发布公告 v0.8.0 ---- - - -# 发布公告 v0.8.0 -这是 Apache YuniKorn (Incubating) 的第一个版本。 - -## Overview -Apache YuniKorn (Incubating) 社区在此版本中修复了 60 个 JIRA:[YuniKorn 在 0.8.0 中修复的 jira 问题](https://issues.apache.org/jira/issues/?filter=12348926) - -发布负责人: Weiwei Yang - -发布日期: 2020-05-04 - -## 主要更新 -### 队列和放置规则 -使用这个新的动态队列管理功能,用户可以设置放置规则来委派队列管理。 -这支持将 K8 命名空间映射到 YuniKorn 队列等用例,而无需预先创建所有队列。 -当运行应用程序需要时,队列是根据放置规则创建的。不再需要时可以删除动态队列。 - -### 插件应用程序管理 -此版本中添加了一个插件化的应用管理框架,通过此功能,YuniKorn 可以轻松地与第三方 K8s operator 集成,例如 Spark-k8s-operator、Flink-k8s-operator 等。 - -### 资源预留 -预留是用于避免在批处理调度方案中大量/挑剔的资源请求被饿死的方法。 - -为来自应用程序的特定请求保留一个节点,从而有效地将其从其他应用程序的可用节点列表中删除。 - -### 节点排序策略插件 -YuniKorn 中有2个关于资源分配的内置节点排序策略(FAIR 和 BinPacking)。 - -节点排序策略扩展为插件,用户可以实现自己的策略并将其使用在调度器内。 - -### 改进的调度性能 -在 K8s 上运行大数据批处理工作负载(例如 Spark)时,调度程序的吞吐量成为主要关注点之一。 -在 YuniKorn 中,有很多优化可以提高性能,例如完全异步事件驱动的系统和低延迟排序策略。 - -根据我们使用 Kubemark 进行的测试,YuniKorn 比默认的 K8s 调度程序快 2 倍以上。 - -## 社区 -YuniKorn 项目自诞生之日起,就受到了好评。我们很感激拥有这样一个多元化的社区,我们有来自微软、LinkedIn、阿里巴巴、苹果、腾讯、英伟达和 Cloudera 的成员来帮助和指导项目的发展。 -非常感谢为发布做出贡献的每个人,以及 Apache YuniKorn (Incubating) 社区中的每个人! - -此版本是许多人直接和间接努力的结果。以下是通过提交补丁直接做出贡献的人:Adam Antal,Akhil Puthenveettil Balan,Bhuvan Mysore,Jetly Jaimin,Kinga Marton,Sunil Govindan,Tao Yang,Wangda Tan,Wanqiang Ji,Weiwei Yang,Wilfred Spiegelenburg,Vinod Kumar Vavilapalli。 - -感谢我们的导师 Felix Cheung、Holden Karau、Jason Lowe、Junping Du 帮助我们建立存储库、权限,并指导我们如何进行开发和以 Apache 方式进行发布。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.9.0.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.9.0.md deleted file mode 100644 index 08e6c7a71ef..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/0.9.0.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -id: rn-0.9.0 -title: 发布公告 v0.9.0 ---- - - -# 发布公告 v0.9.0 -我们非常高兴地宣布 Apache YuniKorn(Incubating) 社区已投票发布 0.9.0。这是 Apache 孵化器项目的第二个版本。 - -Apache YuniKorn (Incubating) 是一个独立的资源调度器,旨在管理和调度容器编排框架上的大数据工作负载,支持本地和云端的用例。 -该版本进一步提升了 Kubernetes 的资源调度和管理能力,并对运行的 Apache Spark、Apache Flink 工作负载进行了一些优化。 - -## 概述 -Apache YuniKorn (Incubating)社区在此版本中修复了 130 多个 JIRA 问题:[YuniKorn 在 0.9.0 中修复的 jira 问题](https://issues.apache.org/jira/issues/?filter=12348947)。 - -发布负责人: Wilfred Spiegelenburg - -发布日期: 2020-08-28 - -## 主要更新 -### 资源配额管理 -这个版本的 YuniKorn 提供了一种无缝方式来管理 Kubernetes 集群的资源配额,它可以作为 [命名空间资源配额](https://kubernetes.io/docs/concepts/policy/resource-quotas/) 的替代方案。 -与命名空间资源配额相比,使用此功能有两个主要优点: -1. 命名空间资源配额是在准入阶段对资源进行统计,与pod是否在使用资源无关。这可能导致无法有效使用命名空间资源的问题。 -2. 命名空间资源配额是扁平化的,不支持分层资源配额管理。 - -如果可能导致命名空间超出其配额,资源配额准入控制器会拒绝 pod,这会增加客户端代码的复杂性。 -通过使用 YuniKorn 提供的资源配额管理,它的设置更加高效、无缝,并提供作业队列来处理常见的调度排序需求。 - -### 作业排序策略: StateAware (状态感知/优化的 FIFO) -StateAware 应用排序策略以 FIFO 顺序排列队列中的作业,并根据条件一一调度。条件是等待应用程序进入可运行状态。这避免了在向单个命名空间(或集群)提交大量批处理作业(例如 Spark)时常见的竞争条件。通过按照特定顺序强制执行作业,它还改进了作业的调度,使其更具可预测性。可以在此处的文档中找到有关此功能的更多说明。 - -### 自动缩放的改进 -在这个版本中,YuniKorn 已经通过大量测试,可以很好地与 Kubernetes 集群自动缩放器配合使用。它通过与 cluster-autoscaler 高效工作,为 Kubernetes 集群带来最大的弹性。在此版本中修复了一些错误并进行了一些改进。 - -### 事件缓存系统 -在此版本中,调度器中添加了一个高效的事件缓存系统。该系统将一些关键调度事件缓存在内存存储中,并在需要时将它们发布到 Kubernetes 事件系统。使用 kubectl 命令可以直接从 Kubernetes 看到更多调度事件。这有助于提高可用性和可调试性。 - -### 更全面的 Web UI -YuniKorn UI 为资源管理提供了更好的集中视图。UI 中添加了一个新的“节点”页面,以显示集群中的详细节点信息。 -应用程序页面已得到增强,它现在提供了一个搜索框,可按队列名称或应用程序 ID 搜索应用程序。 - -## 社区 -Apache YuniKorn 社区很高兴地欢迎新的 committer Gao Li。我们希望看到更多的提交者加入社区并帮助塑造项目。在过去的几个月里,我们会继续在2个不同的时区举行两周一次的社区会议。感谢所有参加这些会议并提供反馈和宝贵想法的社区人员。 - -感谢以下直接为项目贡献代码的贡献者:Adam Antal, Akhil Puthenveettil Balan, Ayub Khan Pathan, Kinga Marton, Manikandan R, Sunil Govindan, Tao Yang, Tingyao Huang, Tim Rots, Wangda Tan, Wanqiang Ji, Weiwei Yang, Wilfred Spiegelenburg。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.0.0.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.0.0.md deleted file mode 100644 index b488eb765a9..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.0.0.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: rn-1.0.0 -title: 发布公告 v1.0.0 ---- - - - -# 发布公告 v1.0.0 -我们很高兴地宣布 Apache YuniKorn 社区已投票发布 1.0.0。这是 Apache YuniKorn 从孵化项目毕业后的第一个版本。 - -Apache YuniKorn 是一个独立的资源调度程序,旨在管理和调度容器编排框架(如 Kubernetes)上的大数据工作负载,用于本地和云端用例。 - -## 概述 -The Apache YuniKorn 社区在此版本中修复了 173 个 [JIRA问题](https://issues.apache.org/jira/issues/?filter=12350818)。 - -发布负责人: Wilfred Spiegelenburg - -发布日期: 2022-05-03 - -## 不兼容的更改 -作为此版本的一部分,我们引入了许多不兼容的更改。 - -### helm 更新 -随着对 helm chart 的更改,从旧版本使用 helm 升级到 1.0.0 可能无法正常执行。 -解决方法是先卸载旧版本,然后执行当前版本的全新安装。 - -### 配置更改 -队列配置现在可以支持度量修饰符。 -这会改变配额值在配置中的解释方式。 -在 1.0.0 之前,所有内存值都被解释为 _megabytes_ 而 vcore(cpu) 值被解释为 _milli cores_。 -从 1.0.0 开始,内存值在 **bytes** 中指定,vcore 在 **cores** [YUNIKORN-629](https://issues.apache.org/jira/browse/YUNIKORN-629) 中指定。 - -要保持配置中值的相同解释,请对 1.0.0 之前的配置进行如下更改: - -| 类型 | 修改 | 旧值 | 新值 | -|--------|--------|--------------|---------------| -| memory | 添加 M | memory: 2048 | memory: 2048M | -| vcore | 添加 m | vcore: 250 | vcore: 250m | -| other | none | license: 1 | license: 1 | - -### 资源展示与通信 -k8shim 将 pod 和其他对象的内存资源转换为 megabytes 可能会导致 Kubernetes 工具和 YuniKorn 占用的大小之间存在差异。 -这可能会导致围绕节点匹配和节点自动缩放而产生问题。 -在 1.0.0 中,所有内存资源在用于计算和通信之前都转换为 **bytes** [YUNIKORN-1105](https://issues.apache.org/jira/browse/YUNIKORN-1105)。 - -所有 REST 响应对象中的资源不再是单个字符串,而是使用每个资源类型的键值对的 JSON 结构。 -新资源 JSON 响应对象的示例: -```json -"allocatedResource": { - "memory": 54000000, - "vcore": 80 -} -``` -REST 返回的内容里不包括或不支持度量修饰符。 -在 REST 响应对象的所有内存值都会转为 **bytes** 。 -CPU值(即vcore)没有改变,仍然使用 **milli cores**。 -REST 文档已更新,从而可以显示新的资源结构 [YUNIKORN-165](https://issues.apache.org/jira/browse/YUNIKORN-165)。 - -### REST 响应中的 Timestamp -REST API 中的所有 Timestamp 现在都返回为自 UTC 1970-01-01 时间以来经过的纳秒数。 -`int64` 中可以显示的时间范围是从 1678 年到 2262 年,详情参见 [Go Time UnixNano](https://pkg.go.dev/time#Time.UnixNano)。 -而早期版本中的 Timestamp 作为 REST 响应内容的一部分被转换为字符串进行创建 [YUNIKORN-1170](https://issues.apache.org/jira/browse/YUNIKORN-1170)。 - -### 删除旧的 REST API 接口 -REST API 已更新为支持指定分区的接口。不带分区参数的旧版本接口已被删除: - -- `/ws/v1/queues` 替换为 `/ws/v1/partition/{partitionName}/queues` -- `/ws/v1/apps` 替换为 `ws/v1/partition/{partitionName}/queues/{queueName}/application` -- `/ws/v1/nodes` 替换为 `/ws/v1/partition/{partitionName}/nodes` - -[YUNIKORN-954](https://issues.apache.org/jira/browse/YUNIKORN-954) - -## 主要更新 - -### 插件模式的技术预览 -作为此版本的一部分,我们添加了一种新的部署模式,该模式建立在 [调度框架](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/) 之上。 -这是调度器 k8shim 工作方式的一个重大变化。由于实现尚未成熟,此种部署模式被视为一种技术预览。 -相关的设计文档可以在网站上找到 [K8s 调度器插件](https://yunikorn.apache.org/zh-cn/docs/next/design/scheduler_plugin) 。 -标准和插件的部署镜像都是通过默认构建程序构建的。 -部署类型之间的选择是 [基于 helm 变量](https://yunikorn.apache.org/zh-cn/docs/next/user_guide/deployment_modes) 来进行的区分。 - -### 内存和 CPU 使用修复 -作为该版本的一部分,主程序和 k8shim 之间的通信已被简化 [YUNIKORN-462](https://issues.apache.org/jira/browse/YUNIKORN-462)。 -使用这些更改简化了 k8shim 中的缓存使用,并修复了许多内存泄漏的问题。 -可以在 jiras [YUNIKORN-876](https://issues.apache.org/jira/browse/YUNIKORN-876) 和 [YUNIKORN-1100](https://issues.apache.org/jira/browse/YUNIKORN-1100) 中查看更详细的信息。 - -如果未执行调度操作,主程序中的空闲循环已被移除,这会降低调度器的 CPU 使用率 [YUNIKORN-1106](https://issues.apache.org/jira/browse/YUNIKORN-1106)。 - -### 安全改进 -为了提高安全性,我们已经进行了许多更改。 - -调度器不再使用 `cluster-admin` 的权限。 -调度器使用的权限与默认调度程序使用的权限相同。 -添加了占位 pod 所需的一些额外权限 [YUNIKORN-997](https://issues.apache.org/jira/browse/YUNIKORN-997)。 - -docker 镜像中的进程不再以 `root` 用户身份运行,而是使用 `yunikorn` 用户 [YUNIKORN-1111](https://issues.apache.org/jira/browse/YUNIKORN-1111)。 - -准入控制器使用的证书会在到期前自动轮换,从而不会导致停机 [YUNIKORN-1119](https://issues.apache.org/jira/browse/YUNIKORN-1119)。 - -占位处理会运行一个简单的暂停镜像。在默认情况下,此暂停镜像是从外部镜像存储库加载的。 -YuniKorn 现在允许为占位操作设置自定义镜像。可以为 deployment 指定一个映镜像。 -它接受一个镜像名称,包括一个主机名,可以使用本地存储库进行 air-gapped deployments [YUNIKORN-638](https://issues.apache.org/jira/browse/YUNIKORN-638)。 -:::tip -占位镜像应该是轻量级的镜像,最好是一个暂停或休眠镜像。 -::: - -### 验证工具 -作为发布的一部分,我们提供了一个新的脚本,可允许创建一个简单的基于 `kind` 的 Kubernetes 集群。 - -您需要解压档案文件并按照 `README.md` 文件中的说明构建镜像。 -运行脚本以获取更多说明并列出验证版本所需的工具: -```shell -./validate_cluster.sh -``` -创建的 `kind` 集群是一个小型但功能齐全的 Kubernetes 集群,这里面部署了 Apache YuniKorn [YUNIKORN-764](https://issues.apache.org/jira/browse/YUNIKORN-764) - -## 社区 -自最新的发布以来,Apache YuniKorn 已从孵化项目毕业。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.1.0.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.1.0.md deleted file mode 100644 index 2bc7232ecaf..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.1.0.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -id: rn-1.1.0 -title: 发布公告 v1.1.0 ---- - - -# 发布公告v1.1.0 -我们很高兴地宣布 Apache YuniKorn 社区已投票发布 1.1.0。 - -Apache YuniKorn是一个独立的资源调度程序,旨在管理和调度容器编排框架(如Kubernetes)上的大数据工作负载,用于本地和云端用例。 - -## 概述 -Apache YuniKorn社区在此版本中修复了89个 [JIRA问题](https://issues.apache.org/jira/issues/?filter=12351692)。 - -发布经理:Peter Bacsko - -发布日期:2022-09-08 - -## 主要更新 -### 增强REST API文档和功能 -REST API现在可以回传 [特定应用程序](https://issues.apache.org/jira/browse/YUNIKORN-1217) 的详细信息,并且列出应用程序的 [待处理分配](https://issues.apache.org/jira/browse/YUNIKORN-1263)。此外REST API的文档也得到了增强。 - -### 多构架构建 -随着ARM构架变得越来越流行,我们现在为 `amd64` 和 `arm64` 构建 [二进制文件和Docker镜像](https://issues.apache.org/jira/browse/YUNIKORN-1215)。 - -### 稳定恢复阶段 -在Yunikorn的恢复阶段发现了几个问题,这些问题主要影响成组调度(例如,正在运行的占位符会 [立即被替换](https://issues.apache.org/jira/browse/YUNIKORN-1197) ,此外也会影响 [Spark工作负载](https://issues.apache.org/jira/browse/YUNIKORN-1217)。 - -### DaemonSet调度 -在此版本之前,DaemonSet pod的调度存在问题。如果节点已满,则这些Pod将不会被安排。然而,DeamonSet pod通常很重要,因为它们执行了所有节点上必须存在的任务,如日志收集和聚合、资源监控、存储管理等,这意味着它们比常规应用程序pod具有优先级。 - -[YUNIKORN-1085](https://issues.apache.org/jira/browse/YUNIKORN-1085) 确保我们有一个可预测的抢占机制,该机制在必要时终止正在运行的pod,以便为DaemonSet pod腾出空间。 - -### 提升E2E测试 -随着我们支持更多的K8s版本,已经编写了额外的 [端到端测试](https://issues.apache.org/jira/browse/YUNIKORN-751) 来增加Yunikorn的覆盖范围。 - -## 社区 -Apache YuniKorn社区很高兴欢迎新的PMC:Peter Bacsko和Manikandan Ramaraj 以及 committer:Ted Lin。 \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.2.0.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.2.0.md deleted file mode 100644 index c540e8e9e38..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.2.0.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -id: rn-1.2.0 -title: 发布公告 v1.2.0 ---- - - - -# 发布公告 v1.2.0 -我们很高兴地宣布Apache YuniKorn社区已投票决定发布1.2.0。 -Apache YuniKorn是一个独立的资源调度器,专为管理和调度在容器编排框架(如Kubernetes)上的大数据工作负载,用于本地和云端使用案例。 - -## 概述 -Apache YuniKorn社区在此版本中修复了150个[JIRA](https://issues.apache.org/jira/issues/?filter=12352194)。 - -发布经理: Manikandan R - -发布日期: 2023-02-02 - -## 亮点 - -### 用户配额追踪 -考虑到其层次结构,用户和群组资源使用情况也在队列级别进行跟踪,以实现属性覆盖偏好。 -详情请阅读[YUNIKORN-984](https://issues.apache.org/jira/browse/YUNIKORN-984)。 - -### 增强用户和群组处理 -用户和群组处理机制得到了增强,开辟了各种检测用户及其关联群组的方法。 -详情请阅读[YUNIKORN-1306](https://issues.apache.org/jira/browse/YUNIKORN-1306)。 - -### 支持应用程序/任务优先级感知调度 -除了基于Fair & FIFO的应用程序分类政策,基于优先级的排序的设计和实现方式也尽可能与Kubernetes标准优先级处理兼容。 -详情请阅读[YUNIKORN-1](https://issues.apache.org/jira/browse/YUNIKORN-1)。 - -### 支持命名空间注解中的任意资源 -现在可以支持命名空间注释中的所有资源类型。 -早期只允许cpu和memory资源类型。 -详情请阅读[YUNIKORN-1275](https://issues.apache.org/jira/browse/YUNIKORN-1275)。 - -### 针对Kubernetes 1.23构建YuniKorn -这将使我们能够继续支持在1.21及更高版本的集群上运行,同时支持更新的调度器功能。 -详情请阅读[YUNIKORN-1348](https://issues.apache.org/jira/browse/YUNIKORN-1348)。 - -### 配置V2 -配置系统已在解决方案中进行了大修,[YUNIKORN-1221](https://issues.apache.org/jira/browse/YUNIKORN-1221): -- 配置更新的REST接口已删除。 -- 新的config map: 通过helm管理yunikorn-defaults。 -- 保留现有config map。 - -详情请阅读 https://yunikorn.apache.org/docs/next/design/config_v2 。 - -### 改进e2e测试 -[YUNIKORN-1491](https://issues.apache.org/jira/browse/YUNIKORN-1491)的一部分涵盖了各种端到端测试的稳定性. - -## 社区 -Apache YuniKorn社区很高兴欢迎新的PMC: Tingyao Huang和committer: Rainie Li。 - diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.3.0.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.3.0.md deleted file mode 100644 index ba8ee816f2a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.3.0.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -id: rn-1.3.0 -title: 发布公告 v1.3.0 ---- - - - -# 发布公告 v1.3.0 -我们很高兴地宣布Apache YuniKorn社区已投票决定发布1.3.0。 -Apache YuniKorn是一个独立的资源调度器,专为管理和调度在容器编排框架(如Kubernetes)上的大数据工作负载,用于本地和云端使用案例。 - -## 概述 -Apache YuniKorn社区在此版本中修复了160个[JIRAs](https://issues.apache.org/jira/issues/?filter=12352568)。 - -发布经理: Yu Teng Chen - -发布日期: 2023-06-09 - -## 亮点 - -### Kubernetes 版本支持 -YuniKorn 1.3.0 支持在 1.21 到 1.26 版本的 Kubernetes 集群上运行。 -**不**支持在 Kubernetes 1.27 上运行,但 YuniKorn 1.4.0 计划支持在 Kubernetes 1.27 上运行。 - -**注**: YuniKorn 1.3.0 是计划中的最后一个版本,它将支持 Kubernetes 1.21 到 1.23; YuniKorn 1.4.0 预计需要 Kubernetes 1.24 或更高版本。 - -请参阅 [YUNIKORN-1699](https://issues.apache.org/jira/browse/YUNIKORN-1699)了解详情。 - -### 抢占支持 -YuniKorn 现在全面支持抢占,包括每个队列的可定制策略。 请参阅抢占 -[设计文件](https://yunikorn.apache.org/docs/next/design/preemption)了解详情。 - -JIRA: [YUNIKORN-1461](https://issues.apache.org/jira/browse/YUNIKORN-1461) - -### 更好地支持 BestEffort pod -YuniKorn 现在跟踪作为队列配额限制的一部分安排的 pod 数量。 -这允许限制队列内的并行性,但也为运行带有`PodQOSBestEffort`调度类的 Kubernetes pod 提供更好的支持(即那些没有请求明确的资源的)。 - -请参阅 [YUNIKORN-1632](https://issues.apache.org/jira/browse/YUNIKORN-1632)了解详情。 - -### 更轻便、更安全的镜像 -YuniKorn 1.3.0 已开始为所有容器使用scratch镜像。 -由于 YuniKorn 不再在我们的容器映像中运送任何第三方软件,因此占用空间更小,安全性也更高。 - -使用scratch镜像的先决条件是将 Web 应用程序从 nginx 迁移到基于 go 的 Web 服务器。 -请参阅 -[YUNIKORN-1672](https://issues.apache.org/jira/browse/YUNIKORN-1672)和 -[YUNIKORN-1535](https://issues.apache.org/jira/browse/YUNIKORN-1535)了解详情。 - -### 准入控制器中的动态命名空间支持 -YuniKorn 准入控制器现在支持每个命名空间注释来控制 YuniKorn 特定的处理。 -以前,只能使用正则表达式的静态列表(仍然支持)来选择命名空间。 - -请参阅 [YUNIKORN-1647](https://issues.apache.org/jira/browse/YUNIKORN-1647)了解详情。 - -### CPU和内存优化 -YuniKorn 1.3.0 包含多项针对 CPU 和内存使用的优化,使该版本成为迄今为止最轻便和最快的版本。 -一些例子: -* [YUNIKORN-1719](https://issues.apache.org/jira/browse/YUNIKORN-1719) - 改进Application.sortRequests()性能 -* [YUNIKORN-1720](https://issues.apache.org/jira/browse/YUNIKORN-1720) - 改进node.preAllocateCheck()性能 -* [YUNIKORN-1722](https://issues.apache.org/jira/browse/YUNIKORN-1722) - calculateNodesResourceUsage()中过多的资源克隆调用 -* [YUNIKORN-1746](https://issues.apache.org/jira/browse/YUNIKORN-1746) - 改进nodeInfoListerImpl.List()性能 - -## 社区 -Apache YuniKorn社区很高兴欢迎新的PMC: Yu Teng Chen和committer: Qi Zhu。 - diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.4.0.md b/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.4.0.md deleted file mode 100644 index 09a4922fc3a..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/release-announce/1.4.0.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: rn-1.4.0 -title: Release Announcement v1.4.0 ---- - - - -# Release Announcement v1.4.0 -我们很高兴地宣布Apache YuniKorn社区已投票决定发布1.4.0。 -Apache YuniKorn是一个独立的资源调度器,专为管理和调度在容器编排框架(如Kubernetes)上的大数据工作负载,用于本地和云端使用案例。 - -## Overview -Apache YuniKorn社区在此版本中修复了270个[JIRAs](https://issues.apache.org/jira/issues/?filter=12352769)。 - -发布经理: Wilfred Spiegelenburg - -发布日期: 2023-11-20 - -## 不兼容变更 - -### Kubernetes 版本支援 -**不**支援在 Kubernetes 1.23 或更早期的版本中运行,对于早期的 Kubernetes 版本请使用 YuniKorn 1.3.0。 - -**备注**: YuniKorn 1.3.0 是支援 Kubernetes 1.23 或更早期版本的最后一个版本。 - -## 亮点 - -### Kubernetes 版本支援 -YuniKorn 1.4.0 支援在版本 1.24 到 1.28 的 Kubernetes 丛集上运行。 - -详细资讯请参阅 [YUNIKORN-1841](https://issues.apache.org/jira/browse/YUNIKORN-1841) - -### PreEnqueue 插件实作 -YuniKorn 添加了调度器插件的 pre-enqueue 调度挂钩。这允许根据队列压力阻止尚未就绪的 Pod 进行门控。Pre-enqueue 调度挂钩是通过 -[KEP-3521](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/3521-pod-scheduling-readiness/README.md) 添加到 Kubernetes 中的。 他将在 Kubernetes 1.27 版本中默认开启。 - -这功能允许在 Kubernetes 资源配额系统之外管理配额,并对于 API 伺服器和预设调度程序的影响较小。此功能仅对于 YuniKorn 的插件实作很重要。 -在标准模式下,YuniKorn 始终在没有外部影响的情况下对 Pod 进行门控。 - -详细资讯请参阅 [YUNIKORN-1844](https://issues.apache.org/jira/browse/YUNIKORN-1844) - -### 范围化日志 -YuniKorn 程式码内的日志纪录建在仅限于部分程式码库。范围日志允许更改部分程式码的日志纪录等级。这使管理员可以更好地控制每个子系统的层级。 - -现在还可以以文字形式指定日志级别,而不仅仅是数字。文件是 [服务配置](https://yunikorn.apache.org/docs/user_guide/service_config) 的一部分。 - -详细资讯请参阅 [YUNIKORN-1823](https://issues.apache.org/jira/browse/YUNIKORN-1823) - -### 移除 Spark Operator 应用程式管理器 -新增了 Spark operator 应用程式管理器以支援 Spark operator 作为外部整合。它为透过 operator 提交的 Spark 应用程式添加了完整的生命周期。 -应用程式管理器从未默认启用,需要自订配置才能启用。 - -此实作导致创建重复的 Spark application,并在作为 YuniKorn 0.11 的 [YUNIKORN-643](https://issues.apache.org/jira/browse/YUNIKORN-643) -中回滚。基本的 Pod 处理涵盖了剩下的功能。为了减少程式码维护,现在也删除了剩余的程式码,而不会失去功能。 - -详细资讯请参阅 [YUNIKORN-2092](https://issues.apache.org/jira/browse/YUNIKORN-2092) - -### 移除 YuniKorn 应用程式 CRD -YuniKorn 1.4.0 已移除应用程式 CRD。添加应用程式 CRD 是为了更简单地将应用程式与 YuniKorn 整合。这种整合从未被使用过,目前所有整合都依赖 -Pod 上的简单标签或是注释。 - -详细资讯请参阅 [YUNIKORN-1672](https://issues.apache.org/jira/browse/YUNIKORN-1672) - -### 应用程式可追溯性 -追踪和故障排除应用程式是专门针对 YuniKorn。 Kubernetes 中没有应用程式的概念。新增了事件系统来公开应用程式、队列和节点的变更以公外部使用。 - -详细资讯请参阅 [YUNIKORN-1628](https://issues.apache.org/jira/browse/YUNIKORN-1628) - -### 建置更新 -在建置二进位档案或映像时,YuniKorn 建置不再依赖集中安装的工具。每个版本都会下载并维护自己的工具集,甚至不会在签出的储存库之间共用。 - -这项变更于 7 月底在 dev@ 邮件单上宣布。 - -请参阅这些 jiras 已了解详细资讯: -- k8shim: [YUNIKORN-1862](https://issues.apache.org/jira/browse/YUNIKORN-1862) and [YUNIKORN-1865](https://issues.apache.org/jira/browse/YUNIKORN-1865) -- core: [YUNIKORN-1868](https://issues.apache.org/jira/browse/YUNIKORN-1868) -- web UI: [YUNIKORN-1873](https://issues.apache.org/jira/browse/YUNIKORN-1873) - -## 社区 -Apache YuniKorn 社区很高兴欢迎新的PMC: Rainie Li 和committers: Hsuang Zong Wu 和 PoAn Yang。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-pages/styles.module.css b/i18n/zh-cn/docusaurus-plugin-content-pages/styles.module.css deleted file mode 120000 index 6c0a04a1603..00000000000 --- a/i18n/zh-cn/docusaurus-plugin-content-pages/styles.module.css +++ /dev/null @@ -1 +0,0 @@ -../../../src/pages/styles.module.css \ No newline at end of file diff --git a/i18n/zh-cn/docusaurus-theme-classic/footer.json b/i18n/zh-cn/docusaurus-theme-classic/footer.json deleted file mode 100644 index 0fdacd30efe..00000000000 --- a/i18n/zh-cn/docusaurus-theme-classic/footer.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "link.item.label.Get Involved": { - "message": "参与" - }, - "link.title.Code Repositories": { - "message": "代码库" - }, - "link.item.label.People": { - "message": "人们" - }, - "link.title.Blog": { - "message": "博客" - }, - "link.title.Community": { - "message": "社区" - } -} diff --git a/i18n/zh-cn/docusaurus-theme-classic/navbar.json b/i18n/zh-cn/docusaurus-theme-classic/navbar.json deleted file mode 100644 index 014cfaacda3..00000000000 --- a/i18n/zh-cn/docusaurus-theme-classic/navbar.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "item.label.Quick Start": { - "message": "快速开始" - }, - "item.label.Roadmap": { - "message": "路线图" - }, - "item.label.Download": { - "message": "下载" - }, - "item.label.Community": { - "message": "社区" - }, - "item.label.People": { - "message": "人员" - }, - "item.label.Incubation Maturity Assessment": { - "message": "成熟度自我评估" - }, - "item.label.Get Involved": { - "message": "进行参与" - }, - "item.label.How to Contribute": { - "message": "如何贡献" - }, - "item.label.Coding Guidelines": { - "message": "编码指南" - }, - "item.label.Reporting Issues": { - "message": "报告问题" - }, - "item.label.Release Procedure": { - "message": "发布流程" - }, - "item.label.Events": { - "message": "事件" - }, - "item.label.Docs": { - "message": "文档" - }, - "item.label.Apache Software Foundation": { - "message": "Apache软件基金会" - }, - "item.label.Sponsorship": { - "message": "赞助" - }, - "item.label.Sponsors": { - "message": "赞助商" - } -} diff --git a/local-build.sh b/local-build.sh index 89b123085d7..fba4c1c7a00 100755 --- a/local-build.sh +++ b/local-build.sh @@ -116,7 +116,7 @@ function print_usage() { cat < - -Yunikorn website adopting Docusaurus manages documentations. -[Docusaurus i18n system](https://docusaurus.io/docs/i18n/tutorial) allows developer to translate documentations. -For adding a new language translation, developers should do following operations. - -## Modifying the docusaurus.config.js for supporting the new language -Assume the translations by a **new language keyword**. -Expected results will be like this figure. -![translation results](./../assets/translationDemo.png) - -Current Yunikorn website include the en and zh-cn documentaions. -If developer want to add a new translation with **new language keyword** including fr, jp, the developers need to modify the `i18n` in `docusaurus.config.js`. -``` -i18n: { - defaultLocale: 'en', - locales: ['en', 'zh-cn', ''], - localeConfigs: { - en: { - label: 'English', - }, - "zh-cn": { - label: '中文', - }, - "": { - label: 'test', - } - }, - }, -``` -## Updating the help information in local-build.sh -Adding the **new language keyword** to the locale list in `print_usage` function. -``` -Usage: $(basename "$0") run [locale] | build | clean | help - run build the website, and launch the server in a docker image. - a locale can be specified, currently supported: "en", "zh-cn", "" -``` - -## Copying latest files to i18n -``` -mkdir -p i18n//docusaurus-plugin-content-docs/current -cp -r docs/** i18n//docusaurus-plugin-content-docs/current -mkdir -p i18n//docusaurus-plugin-content-pages -cp -r src/pages/** i18n//docusaurus-plugin-content-pages -mkdir -p i18n//docusaurus-theme-classic -``` - -## Adding the translated information in sidebar.json and footer.json -Create sidebar.json and and footer.json in docusaurus-theme-classic. -For example, the footer.json context is following. -``` -{ - "link.item.label.Get Involved": { - "message": "参与" - }, - "link.title.Code Repositories": { - "message": "代码库" - }, - "link.item.label.People": { - "message": "人们" - }, - "link.title.Blog": { - "message": "博客" - }, - "link.title.Community": { - "message": "社区" - } -} -``` - - - -## linking img, assest and styles.module.css -Creating linking files in the `i18n/new language keyword/docusaurus-plugin-content-pages`. - -``` -# cleaning the duplicate files -rm -rf img -rm styles.module.css -# linking -ln -s ../../../static/img -ln -s ../../../src/pages/styles.module.css -``` - -Creating the linking file in the 'i18n/new language keyword/docusaurus-plugin-content-docs/current'. -``` -# cleaning the duplicate files -rm -rf assests -# linking -ln -s ../../../../docs/assets -``` - -## Adopting relative paths -There are some image urls adopting absolute path in `src/pages/index.js` and adopting absolute path could cause png missing. -Developers could make sure that the img link in `/i18n/new language keyword/docusaurus-plugin-content-pages/index.js` is work. -For example, there is a `resource-scheduling.png` in `index.js` and the png url is `/img/resource-scheduling.png`. -``` -/img/resource-scheduling.png -> ./img/resource-scheduling.png -``` -## Test -``` -./local-build.sh run -``` -![Building website](./../assets/translationBuilding.png) diff --git a/versioned_docs/version-1.3.0/developer_guide/translation.md b/versioned_docs/version-1.3.0/developer_guide/translation.md deleted file mode 100644 index 2ab5a0d3188..00000000000 --- a/versioned_docs/version-1.3.0/developer_guide/translation.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: translation -title: Translation ---- - - - -Yunikorn website adopting Docusaurus manages documentations. -[Docusaurus i18n system](https://docusaurus.io/docs/i18n/tutorial) allows developer to translate documentations. -For adding a new language translation, developers should do following operations. - -## Modifying the docusaurus.config.js for supporting the new language -Assume the translations by a **new language keyword**. -Expected results will be like this figure. -![translation results](./../assets/translationDemo.png) - -Current Yunikorn website include the en and zh-cn documentaions. -If developer want to add a new translation with **new language keyword** including fr, jp, the developers need to modify the `i18n` in `docusaurus.config.js`. -``` -i18n: { - defaultLocale: 'en', - locales: ['en', 'zh-cn', ''], - localeConfigs: { - en: { - label: 'English', - }, - "zh-cn": { - label: '中文', - }, - "": { - label: 'test', - } - }, - }, -``` -## Updating the help information in local-build.sh -Adding the **new language keyword** to the locale list in `print_usage` function. -``` -Usage: $(basename "$0") run [locale] | build | clean | help - run build the website, and launch the server in a docker image. - a locale can be specified, currently supported: "en", "zh-cn", "" -``` - -## Copying latest files to i18n -``` -mkdir -p i18n//docusaurus-plugin-content-docs/current -cp -r docs/** i18n//docusaurus-plugin-content-docs/current -mkdir -p i18n//docusaurus-plugin-content-pages -cp -r src/pages/** i18n//docusaurus-plugin-content-pages -mkdir -p i18n//docusaurus-theme-classic -``` - -## Adding the translated information in sidebar.json and footer.json -Create sidebar.json and and footer.json in docusaurus-theme-classic. -For example, the footer.json context is following. -``` -{ - "link.item.label.Get Involved": { - "message": "参与" - }, - "link.title.Code Repositories": { - "message": "代码库" - }, - "link.item.label.People": { - "message": "人们" - }, - "link.title.Blog": { - "message": "博客" - }, - "link.title.Community": { - "message": "社区" - } -} -``` - - - -## linking img, assest and styles.module.css -Creating linking files in the `i18n/new language keyword/docusaurus-plugin-content-pages`. - -``` -# cleaning the duplicate files -rm -rf img -rm styles.module.css -# linking -ln -s ../../../static/img -ln -s ../../../src/pages/styles.module.css -``` - -Creating the linking file in the 'i18n/new language keyword/docusaurus-plugin-content-docs/current'. -``` -# cleaning the duplicate files -rm -rf assests -# linking -ln -s ../../../../docs/assets -``` - -## Adopting relative paths -There are some image urls adopting absolute path in `src/pages/index.js` and adopting absolute path could cause png missing. -Developers could make sure that the img link in `/i18n/new language keyword/docusaurus-plugin-content-pages/index.js` is work. -For example, there is a `resource-scheduling.png` in `index.js` and the png url is `/img/resource-scheduling.png`. -``` -/img/resource-scheduling.png -> ./img/resource-scheduling.png -``` -## Test -``` -./local-build.sh run -``` -![Building website](./../assets/translationBuilding.png) diff --git a/versioned_docs/version-1.4.0/developer_guide/translation.md b/versioned_docs/version-1.4.0/developer_guide/translation.md deleted file mode 100644 index 2ab5a0d3188..00000000000 --- a/versioned_docs/version-1.4.0/developer_guide/translation.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: translation -title: Translation ---- - - - -Yunikorn website adopting Docusaurus manages documentations. -[Docusaurus i18n system](https://docusaurus.io/docs/i18n/tutorial) allows developer to translate documentations. -For adding a new language translation, developers should do following operations. - -## Modifying the docusaurus.config.js for supporting the new language -Assume the translations by a **new language keyword**. -Expected results will be like this figure. -![translation results](./../assets/translationDemo.png) - -Current Yunikorn website include the en and zh-cn documentaions. -If developer want to add a new translation with **new language keyword** including fr, jp, the developers need to modify the `i18n` in `docusaurus.config.js`. -``` -i18n: { - defaultLocale: 'en', - locales: ['en', 'zh-cn', ''], - localeConfigs: { - en: { - label: 'English', - }, - "zh-cn": { - label: '中文', - }, - "": { - label: 'test', - } - }, - }, -``` -## Updating the help information in local-build.sh -Adding the **new language keyword** to the locale list in `print_usage` function. -``` -Usage: $(basename "$0") run [locale] | build | clean | help - run build the website, and launch the server in a docker image. - a locale can be specified, currently supported: "en", "zh-cn", "" -``` - -## Copying latest files to i18n -``` -mkdir -p i18n//docusaurus-plugin-content-docs/current -cp -r docs/** i18n//docusaurus-plugin-content-docs/current -mkdir -p i18n//docusaurus-plugin-content-pages -cp -r src/pages/** i18n//docusaurus-plugin-content-pages -mkdir -p i18n//docusaurus-theme-classic -``` - -## Adding the translated information in sidebar.json and footer.json -Create sidebar.json and and footer.json in docusaurus-theme-classic. -For example, the footer.json context is following. -``` -{ - "link.item.label.Get Involved": { - "message": "参与" - }, - "link.title.Code Repositories": { - "message": "代码库" - }, - "link.item.label.People": { - "message": "人们" - }, - "link.title.Blog": { - "message": "博客" - }, - "link.title.Community": { - "message": "社区" - } -} -``` - - - -## linking img, assest and styles.module.css -Creating linking files in the `i18n/new language keyword/docusaurus-plugin-content-pages`. - -``` -# cleaning the duplicate files -rm -rf img -rm styles.module.css -# linking -ln -s ../../../static/img -ln -s ../../../src/pages/styles.module.css -``` - -Creating the linking file in the 'i18n/new language keyword/docusaurus-plugin-content-docs/current'. -``` -# cleaning the duplicate files -rm -rf assests -# linking -ln -s ../../../../docs/assets -``` - -## Adopting relative paths -There are some image urls adopting absolute path in `src/pages/index.js` and adopting absolute path could cause png missing. -Developers could make sure that the img link in `/i18n/new language keyword/docusaurus-plugin-content-pages/index.js` is work. -For example, there is a `resource-scheduling.png` in `index.js` and the png url is `/img/resource-scheduling.png`. -``` -/img/resource-scheduling.png -> ./img/resource-scheduling.png -``` -## Test -``` -./local-build.sh run -``` -![Building website](./../assets/translationBuilding.png) diff --git a/versioned_sidebars/version-1.2.0-sidebars.json b/versioned_sidebars/version-1.2.0-sidebars.json index e3845f47be0..d286fafb802 100644 --- a/versioned_sidebars/version-1.2.0-sidebars.json +++ b/versioned_sidebars/version-1.2.0-sidebars.json @@ -45,7 +45,6 @@ "developer_guide/dependencies", "developer_guide/deployment", "developer_guide/openshift_development", - "developer_guide/translation", { "type": "category", "label": "Designs", diff --git a/versioned_sidebars/version-1.3.0-sidebars.json b/versioned_sidebars/version-1.3.0-sidebars.json index 72b3a39e167..87cb03b94a0 100644 --- a/versioned_sidebars/version-1.3.0-sidebars.json +++ b/versioned_sidebars/version-1.3.0-sidebars.json @@ -47,7 +47,6 @@ "developer_guide/dependencies", "developer_guide/deployment", "developer_guide/openshift_development", - "developer_guide/translation", { "type": "category", "label": "Designs", diff --git a/versioned_sidebars/version-1.4.0-sidebars.json b/versioned_sidebars/version-1.4.0-sidebars.json index 6d2f169b011..4ef82fd0e74 100644 --- a/versioned_sidebars/version-1.4.0-sidebars.json +++ b/versioned_sidebars/version-1.4.0-sidebars.json @@ -57,7 +57,6 @@ "developer_guide/dependencies", "developer_guide/deployment", "developer_guide/openshift_development", - "developer_guide/translation", { "type": "category", "label": "Designs",